C#编码规范
程序员文章站
2023-08-25 14:03:06
记录 编码约定 学习过程。 命名空间约定 如果没有使用using指令,项目也没有默认导入合适的命名空间,访问这些命名空间或者类型时,则需要“完全限定名称”。 namespace ConsoleApp4 { class Program { static void Main(string[] args) ......
记录 学习过程。
命名空间约定
如果没有使用using指令,项目也没有默认导入合适的命名空间,访问这些命名空间或者类型时,则需要“完全限定名称”。
namespace consoleapp4 { class program { static void main(string[] args) { // 在这里system.diagnostics是“完全限定名称” var tracesource = new system.diagnostics.tracesource(""); } } }
如果使用了using指令,则不需要“完全限定名称”。
using system.diagnostics; namespace consoleapp4 { class program { static void main(string[] args) { var tracesource = new tracesource(""); } } }
代码布局约定
- 不轻易更改编辑器的设置,通常使用默认的,特别是格式设置和制表符。
- 每行一条语句,每行一个声明。
string[] strs = new string[] { "aa","bb","cc"}; string str = "hello"; int num = 4; if (num == 9) { }
- 一行写不完的语句,断行写则需要缩进一个制表符位,除了起头的第一行,后面无论再断多少行都是一个制表符位。
string[] strs = new string[] { "aa","bb","cc"}; var query = strs.where(x => x.length == 2 && x.contains("b")). select(x => new { name = x, age = 8 });
- 属性和方法之间至少一个空行
public int myproperty { get; set; } public int myproperty1 { get; set; } void test() { }
- 使用括号突出表达式的字句。
int val1 = 1; int val2 = 3; int val3 = 4; if ((val1 > val2) && (val1 > val3)) { }
注释约定
单独的行,而非代码末尾;大写字母开头,断行换小写;句点结束注释文本;注释和文本之间留一个空格。
不要在注释周围创建格式化的星号块???没看懂。
下面放一段ilspy源码
/// <summary> /// sets the value of a dependency property on <paramref name="targetobject"/> using a markup extension. /// </summary> /// <remarks>this method does not support markup extensions like x:static that depend on /// having a xaml file as context.</remarks> public static void setvaluetoextension(this dependencyobject targetobject, dependencyproperty property, markupextension markupextension) { // this method was copied from icsharpcode.core.presentation (with permission to switch license to x11) if (targetobject == null) throw new argumentnullexception(nameof(targetobject)); if (property == null) throw new argumentnullexception(nameof(property)); if (markupextension == null) throw new argumentnullexception(nameof(markupextension)); var serviceprovider = new setvaluetoextensionserviceprovider(targetobject, property); targetobject.setvalue(property, markupextension.providevalue(serviceprovider)); }
隐式类型var
当明显可以从赋值右侧推导左侧变量类型时,使用var。当精确的类型不太重要时,使用var。
var var1 = "this is clearly a string."; var var2 = 27; var var3 = convert.toint32(console.readline());
右侧类型不明确时,则可以声明一个明确的类型。
using system; namespace consoleapp4 { class program { static void main(string[] args) { string test = getobject(2); int test1 = getobject(1); decimal test2 = getobject(3); } static dynamic getobject(int x) { switch (x) { case 1:return 2; case 2:return ""; default:return 8m; } } } }
在for循环使用var,下面的i分别推导为int、decimal。
for (var i = 0; i < 10000; i++) { } for(var i = 0m; i < 10m; i = i + 0.1m) { }
在foreach中不建议使用var。
datatable datatable = new datatable(); // 枚举值:enumerablerowcollection<datarow>,可以推row为datarow。 foreach (var row in datatable.asenumerable()) { } // 虽然可以推,但声明明确的类型会让代码更加清晰,因为无法在枚举泛型类型里明显看出当前row的类型。 foreach (datarow row in datatable.asenumerable()) { } // 枚举值:datarowcollection,不声明明确类型row则为object?,因此需要声明明确的类型。 foreach (datarow row in datatable.rows) { }
符号类型
使用时,符号类型优先于无符号类型。short、int、long。 ushort、uint、ulong。
数组
使用间接的语法声明数组
// 这时候,无法从右侧推导变量类型。 string[] vowels1 = { "a", "e", "i", "o", "u" }; // 可以推导,左侧使用var var vowels2 = new string[] { "a", "e", "i", "o", "u" }; var vowels3 = new string[2]; vowels3[0] = "a"; vowels3[1] = "e";
委托
使用简短的语法为委托赋值。
static void main(string[] args) { del exampledel2 = delmethod; var del3 = new del(delmethod); } public delegate void del(string message); public static void delmethod(string str) { console.writeline("delmethod argument: {0}", str); }
using
如果使用try...finally...,且在finally只有释放资源的代码,考虑替换成using,using会自动调用dispose方法。
font font1 = new font("arial", 10.0f); try { } finally { font1.dispose(); } using(font font=new font("arial", 10.0f)) { }
new运算符
能推导类型使用var,对象实例的构造函数没有参数则不必调用构造函数。
// 不必使用new exampleclass() var instance3 = new exampleclass { name = "desktop", id = 37414, location = "redmond", age = 2.3 }; var instance4 = new exampleclass(); instance4.name = "desktop"; instance4.id = 37414; instance4.location = "redmond"; instance4.age = 2.3;
事件处理
在事件比较简短、且只使用一次的情况下,可以考虑使用lambda表达式。
public form1() { initializecomponent(); this.click += (s, e) => { messagebox.show(s.tostring()); }; }
静态成员
派生对象时,不建议添加和基类具有相同名称的静态成员。
using system; namespace consoleapp4 { class program { static void main(string[] args) { exampleclass2.test(); } } class exampleclass { public static void test() { console.writeline("调用exampleclass test"); } } class exampleclass2:exampleclass { // 同名容易引起混乱,隐性覆盖了exampleclass的test方法。 public static void test() { console.writeline("调用exampleclass2 test"); } } class exampleclass3 : exampleclass { // 使用new,说明有意覆盖。 public new static void test() { } } }
linq查询表达式
匿名类型遵循pascal大小写格式(与骆驼命名法类似,骆驼命名法是首字母小写,而pascal帕斯卡命名法是首字母大写)。
var localdistributors = from customer in customers join distributor in distributors on customer.city equals distributor.city select new { customer = customer, distributor = distributor, custometorid = customer.id };
在查询变量和范围变量的声明中使用隐式类型化,虽然查询变量没有明确标有var关键字,但确实隐式化了。
using system; using system.linq; namespace consoleapp4 { class program { static void main(string[] args) { var customers = new system.collections.generic.list<customer>(); var distributors = new system.collections.generic.list<distributor>(); var localdistributors = from customer in customers join distributor in distributors on customer.city equals distributor.city select new { customer = customer, distributor = distributor, custometorid = customer.id }; } } internal class distributor { public object city { get; internal set; } } internal class customer { public object city { get; internal set; } public object id { get; internal set; } } }
对其from字句下面的查询语句。
// 第一种:from语句不和声明变量同一行,则在下一行缩进一个制表符。
var localdistributors = from customer in customers join distributor in distributors on customer.city equals distributor.city select new { customer = customer, distributor = distributor, custometorid = customer.id };
// 第二种:from语句和声明变量同一行 var localdistributors = from customer in customers join distributor in distributors on customer.city equals distributor.city select new { customer = customer, distributor = distributor, custometorid = customer.id };