起因

通常使用Protobuf的步骤为

  1. 定义 .proto 文件
  2. 使用 protoc 生成对应语言的代码

以生成C#代码为例,使用如下命令:

protoc -I ../protos --csharp_out ../Generated --grpc_out ../Generated \
--plugin=protoc-gen-grpc=grpc_csharp_plugin ../protos/ExportOffice.proto

其生成的C#代码像这样:

public const int TemplatePathFieldNumber = 1;
private string templatePath_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TemplatePath {
get { return templatePath_; }
set {
templatePath_ = pb::ProtoPreconditions.CheckNotNull(value, value")
}
}

C#开发通常使用Pascal、Camel二种命名规范

  • 用Pascal规则来命名类名、属性、方法和事件
  • 用Camel规则来命名成员变量、局部变量和方法的参数

上面代码中成员变量 templatePath_ 应该是 Camel 命名规则,但 Camel 命名规则没有以_结尾的。

我的项目中为规范化代码我使用了 StyleCop 自动代码审查工具,它会将不符合命名规范的代码视为编译错误,这种命名的代码是编译不过的,并且 StyleCop 并没有提供忽略指定类文件的功能,只能改代码使其符合命名规范了。

解决

代码是自动生成的手动肯定肯定不现实的,那么就自动改。可以用正匹配到这种命名的变量然后替换即可,于是我写了个shell脚本可以做这件事,代码如下:

#!/usr/bin/env bash

#Usage: xxx.sh

TOOLS_DIR=/mnt/d/Program_Code/Package/gRPC/Tools/linux_x64

BASH_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $BASH_DIR rm ../Generated/*.cs $TOOLS_DIR/protoc -I ../protos --csharp_out ../Generated --grpc_out ../Generated \
--plugin=protoc-gen-grpc=$TOOLS_DIR/grpc_csharp_plugin ../protos/ExportOffice.proto sed -ri -e 's/\b([a-zA-Z0-9_]+)_\b/_\1/g' \
-e 's/\b(descriptor)\b/_\1/g' \
-e '1s/^/\xef\xbb\xbf/' ../Generated/*.cs

这个脚本做了3件事

  1. 生成C#代码
  2. 替换不符合命名规范的成员变量
  3. 添加UTF8 BOM头

使用时需要将 TOOLS_DIR 变量修改为 protoc 所在目录

解决Protobuf生成的C#代码命名不规范问题的更多相关文章

  1. Derek解读Bytom源码-protobuf生成比原核心代码

    作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...

  2. k.tt 研究下生成的逻辑代码:从壹开始前后端分离 [.netCore 填坑 ] 三十二║ 四种方法快速实现项目的半自动化搭建

    更新 1.更新小伙伴 @大龄Giser 提出好点子:试试VS的插件扩展:VSIX.ItemProject等,将T4模板给制作插件,这里先记下,有懂的小伙伴可以自己先试试,我会在以后更新. 2.感谢小伙 ...

  3. 自动生成Code First代码

    自动生成Code First代码 在前面的文章中我们提到Entity Framework的“Code First”模式也同样可以基于现有数据库进行开发.今天就让我们一起看一下使用Entity Fram ...

  4. mybatis自定义代码生成器(Generator)——自动生成model&dao代码

    花了两天的时间研究了下mybatis的generator大体了解了其生成原理以及实现过程.感觉generator做的非常不错,给开发者也留足了空间.看完之后在generator的基础上实现了自定义的生 ...

  5. 【gRPC使用问题2】按照问题1操作生成出来的代码,import的proto内定义的message未生成出来

    1.问题 其实元数据proto里是有定义message,但是 这个message的定义是在另一个 proto文件内,被 api.proto导入,事实上 我是对 api.proto 进行命令行生成代码的 ...

  6. 如何快速编写和调试 Emit 生成 IL 的代码

    .NET Core/.NET Framework 的 System.Reflection.Emit 命名空间为我们提供了动态生成 IL 代码的能力.利用这项能力,我们能够在运行时生成一段代码/一个方法 ...

  7. 将excel中某列数据中,含有指定字符串的记录取出,并生成用这个字符串命名的txt文件

    Python 一大重要的功能,就是可处理大量数据,那分不开的即是使用Excel表格了,这里我做下学习之后的总结,望对我,及广大同仁们是一个帮助Python处理Excel数据需要用到2个库:xlwt 和 ...

  8. 实战:一键生成前后端代码,Mybatis-Plus代码生成器让我舒服了

    实战:一键生成前后端代码,Mybatis-Plus代码生成器让我舒服了 前言 在日常的软件开发中,程序员往往需要花费大量的时间写CRUD,不仅枯燥效率低,而且每个人的代码风格不统一.MyBatis-P ...

  9. [Java 开源项目]一款无需写任何代码,即可一键生成前后端代码的工具

    作者:HelloGitHub-小鱼干 JeecgBoot 是一款基于代码生成器的低代码开发平台,零代码开发.JeecgBoot 采用开发模式:Online Coding 模式-> 代码生成器模式 ...

随机推荐

  1. linux学习笔记 4建立用户

    一般用法  #useradd mysql 含义 创建 mysql用户 特殊用法 1> #useradd -d /usr/cjh -m cjh 含义:创建cjh用户 产生一个主目录 /usr/cj ...

  2. Python、进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  3. JS获取IOS版本号

    var str= navigator.userAgent.toLowerCase(); var ver=str.match(/cpu iphone os (.*?) like mac os/); if ...

  4. 一道有意思的找规律题目 --- CodeForces - 964A

    题目连接: https://vjudge.net/problem/1502082/origin 这一题第一眼看过去貌似是模拟,但是根据其范围是1e9可以知道,如果暴力解基本上是不可能的(不排除大佬级优 ...

  5. 洛谷P1309 瑞士轮(归并排序)

    To 洛谷.1309 瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平, ...

  6. 英语口语练习系列-C24-杂技-问候语-乡愁

    1. 词汇-杂技 acrobatics noun [ U ] UK /ˌæk.rəˈbæt.ɪks/ US /ˌæk.rəˈbæt̬.ɪks/ the skills of an acrobat 杂技 ...

  7. BZOJ3070 : [Pa2011]Prime prime power 质数的质数次方

    对于$a^b$,如果$b=2$,那么在$[\sqrt{n},\sqrt{n}+k\log k]$内必定能找到$k$个质数作为$a$. 筛出$n^{\frac{1}{4}}$内的所有质数,暴力枚举所有落 ...

  8. redis:order set有序集合类型的操作(有序集合)

    1. order set有序集合类型的操作(有序集合) 有序集合是在无序集合的基础上加了一个排序的依据,这个排序依据叫score,因此声明一个集合为有序集合的时候要加上score(作为排序的依据) 1 ...

  9. NodeJS多进程

    NodeJS多进程 Node以单线程的方式运行,通过事件驱动的方式来减少开销车,处理并发.我们可以注册多进程,然后监听子进程的事件来实现并发 简介 Node提供了child_process模块来处理子 ...

  10. C C++ 数字后面加 LL是什么意思

    long long类型,在赋初值的时候,如果大于2的31次方-1,那么后面需要加上LL