• 基础记录--.NET开发规范


     1.有关简洁:

         使用#region标记代码区域,便于折叠

    2.有关命名:

    • 使用有意义的名称,如 IsDepartmentReadyToOfferJob
    • 使用完整单词,帕斯卡(Pascal)和骆驼(Camel)写法
    NumberOfArgumentsIn
    nargin

        根据含义而非类型命名

    ParcelName
    strParcelName

          不要用大小写区分名称

    • 像普通词一样书写缩略词:XmlReader; System.Linq
    • 用复数形式书写集合名称
    • 习惯性后缀(前缀):
    抽象基类
    -Base
    接口
    I-
    异常
    -Exception
    事件参数
    -EventArgs
    事件委托
    -EventHandler
    特性
    -Attribute
    泛型类型参数
    T-
    • 给实现一种设计模式的类加上模式名称,例如:工厂模式 - xxxFactory
    • 泛型参数的命名:使用单个大写字母,如T, U等。需要时,写成TKey, TValue等
    • 枚举的命名:普通枚举用单数名词,位域枚举用复数名词。
    • 接口的命名:使用I-加名词为声明服务的接口命名,使用I-加形容词为描述能力的接口命名。(例:IEnumerable和IEnumerator)
    • 用能体现布尔值特征的名称给布尔类型命名:IsXxx,HasXxx,CanXxx
    • 方法的命名:用动[宾]结构、帕斯卡写法
    • 变量和方法参数命名:用名词性结构、骆驼写法
    • 成组的私有字段、公共属性和构造函数形参:_item, Item, item。见4.6节代码示例
    • 习惯中允许使用的标准“一次性”变量名(只限这几个):
    i, j, k
    循环变量(类型:System.Int32)
    o
    System.Object
    s
    System.String
    e
    事件实参(基类:System.EventArgs)
    ex
    异常(基类:System.Exception)
    g
    System.Drawing.Graphics
    x, y, z
    Lambda表达式的形参
    •  命名空间的命名:公司名.产品名.技术/模块名。将相互依赖的类型放在同一命名空间下。不要污染框架命名空间(例如在System命名空间中添加类型)。

    3.有关字面量

     

    • 避免使用数值字面量。使用常量表示一个值,使用枚举明确指示一个状态。
    • 使用枚举代替布尔值。
    • 使用标准形式书写浮点字面量。不必写f,d(一般只用double),但要对整数写上小数点。用科学计数法时注意小数点前只能有一位数,且不能是0。
    • 字符串字面量应该总是赋给变量使用。用string.Empty代替空串字面量。

     

    4 最佳实践

     

    4.1 使用属性

     

    • 属性是函数成员,没有存储空间。例:属性不能做ref/out参数。
    • 将成员字段全部私有,使用属性来获取,不需修改就不设set。
    • 属性应简单、低成本、无副作用、与调用顺序无关。
    • 属性返回集合应该总是只读。(用户代码可以清空集合、再添加元素,但不允许使对象引用改变)
    • 属性返回其他引用类型也应该尽量考虑只读,用户代码依然可以修改成员。
    • 特殊的属性:索引器

     

    [思考题2]

     

    复制代码
    string s = "abcdeeg";
    s[5] = 'f';
    复制代码

     

    以上代码在C++和C#中是否都合法?是否都有效?

     

    4.2 使用不可变值类型

     

    • 为“值”语义使用struct。所谓值语义就是一种状态、属性,例如点(坐标)、颜色(分量)等,多具有短小数据量的特点。
    • 为struct的字段添加readonly修饰符,成为不可变(Immutable)类型。成员函数返回新实例,而不是修改this实例。
    • 值类型的成员字段只应使用基本CTS类型。

     

    4.3 转换

     

    • 用as和is运算符代替显式引用转换
    • 基本类型的转换要使用System.Convert类
    • 避免装箱和拆箱

     

    4.4 字符串

     

    [思考题3]检测一个字符串str是否以"abc"开头,有两种方法(不使用StartsWith):

     

    复制代码
    str.SubString(0, 3) == "abc";
    str.IndexOf("abc") == 0;
    复制代码

     

    请问哪种方法好,为什么? 

     

    CLR中的字符串是不可变类型,字符串分配是一项昂贵的操作。因此我们有以下最佳做法:

     

    • 用string.Empty代替空串字面量。
    • 用str.Length == 0或string.IsNullOrEmpty(str)检测空串,后者还兼容空引用。
    • 反复使用的字符串应当创建变量多次引用而不是每次都使用字面量(每出现一次字面量就要重新分配一次字符串)。
    • 不分大小写的比较应当用string.Compare(str1, str2, true)而不是str1.ToUpper() == str2.ToUpper()。
    • 考虑使用string.Format()方法而不是字符串拼接来输出结果。
    • 大量拼接字符串要使用StringBuilder类。

     

    4.5 使用查询表达式代替循环

     

    函数式编程为C#带来了高可读性的声明式语法。循环是一种命令式语法,在声明式语法中相应的是对集合的mapping操作。

     

    以下代码生成前100个完全平方数:

     

    复制代码
    var squares = Enumerable.Range(1, 100).Select(x => x * x);
    复制代码

     

    返回int数组:squares.ToArray();

     

    返回List<int>集合:squares.ToList();

     

    以下代码对集合foos中每个元素执行DoSomething()成员方法:

     

    复制代码
    foos.ForEach(x => x.DoSomthing());
    复制代码

     

    以下代码选出foos中大于100的元素:

     

    复制代码
    var q = foos.Where(x => x > 100);
    复制代码

     

    points中点按到原点距离排序:

     

    复制代码
    var q = points.OrderBy(x => x.DistTo(new Point(0, 0)));
    复制代码

     

    foos中平方最小的数:

     

    复制代码
    double minSq = foos.Min(x => x * x);
    double min = foos.Distinct().Single(x => x * x == minSq);
    复制代码

     

    foos中的数是否有大于100的(是否都大于100)

     

    复制代码
    foos.Any(x => x > 100);
    foos.All(x => x > 100);
    复制代码

     

    4.6 返回多个值

     

    • 在Matlab中可以用矩阵返回多个值,这就是元组(Tuple)的概念。当函数需要返回多个值时,应当使用元组而不是使用输出参数。.NET 4.0中提供了Tuple泛型类,位于System命名空间。在3.5以下版本可以考虑自己实现。

     

    复制代码
    public class Tuple<T1, T2>
    {
        private T1 _item1;
        private T2 _item2; 
    
        public T1 Item1 { get { return _item1; } }
        public T2 Item2 { get { return _item2; } } 
    
        public Tuple(T1 item1, T2 item2)
        {
            _item1 = item1;
            _item2 = item2;
        }
    } 
    
    public class TupleList<T1, T2> : List<Tuple<T1, T2>>
    {
        public void Add(T1 item1, T2 item2)
        {
            base.Add(new Tuple<T1, T2>(item1, item2));
        }
    }
    复制代码

     

    • 在任何时候都应避免使用ref/out传递参数,尤其对引用类型(禁止引用的引用)。尝试改进你的设计。

     

    4.7 对象初始化

     

    复制代码
    Button btn = new Button { Text = "Click me!", BackColor = Color.FromArgb(255, 255, 255) };
    btn.Click += (sender, e) => MessageBox.Show("Hello!");
    复制代码

     

    4.8 小函数

     

    • 将大函数分拆成小函数。这样做的好处有:
      • 合并重复代码,便于维护
      • 增加函数层级,便于调试
    • 方法参数也不宜过多,否则也应考虑拆分。

     

    4.9 using块和finally

     

    以下代码编译成相同IL:

     

    复制代码
    // 1. Example Using clause:
    using (myConnection = new SqlConnection(connString))
    {
    myConnection.Open();
    } 
    
    // 2. Example Try / Catch block:
    try
    {
    myConnection = new SqlConnection(connString);
    myConnection.Open();
    }
    finally
    {
    myConnection.Dispose();
    }
    复制代码

     

    4.10 使用泛型集合

     

    • 不要使用非泛型的ArrayList,这会带来不必要的装箱和拆箱。使用System.Collections.Generic命名空间中的容器类型。
    • 代替数组的首选:List<T>。如被用户代码获取应该以只读属性形式提供。如果要真的使集合不可修改,可用ReadOnlyCollection<T>(System.Collections.ObjectModel)
    • 集合做参数禁止ref/out传递(造成引用的引用)。值传递即可达到修改集合元素的目的。
    • 在多个函数间返回、传递的集合考虑用接口类型IEnumerable<T>和yield关键字。连续的LINQ语句考虑不急于调用ToList或ToArray。
    • 其他常用集合:Dictionary<TKey, TValue>; SortedSet<T>(.NET 4) 

     

    4.11 充分利用BCL

     

    • BCL中提供了很多常用算法,并且还在不断扩充。例如,.NET 4增加了System.Numerics命名空间,目前包括BigIntegar和Complex类,而在bcl.codeplex.com上已经放出了BigRational类的候选版和源代码。
    • 尽可能只依赖BCL,减少第三方依赖。
    • 对字符串的操作都有简单的方法可以调用。用这些方法不仅能更方便省时、稳定高效,而且能使你的代码趋向于可读性强的声明式风格。
    • 尽可能只用系统定义的委托,而不是自己定义委托类型。系统定义的委托包括:各种泛型参数数目的Func, Action; 一个Predicate<T>;各种EventHandler。以下是一个高阶函数的应用实例:

     

    复制代码
    Func<Color, EventHandler> changeControlColor =
    x => (sender, e) => (sender as Control).BackColor = x;
    button1.Click += changeControlColor(Colors.Red);
    复制代码

     

    4.12其他

     

    • 使用虚函数和多态而不是频繁使用引用转换
    • 创建枚举0值表示未初始化、无效、未指定或默认
    • 总是在派生类构造函数的初始化列表中列出所有基构造函数
    • 总是重写ToString()方法

     

  • 相关阅读:
    使用unlist将日期型数据的列表转换为向量时,出现的异常
    => in Scala
    Scala Beginner
    .net Core 调用微信Jsapi接口,H5解析二维码
    TextBoxFor控件的扩展---Bootstrap在mvc上的应用
    Dapper Vs Dbentry
    外地手机号码,请在号码前加拨0
    Sql 2012 远程数据库连接
    DbEntry在Vs2012里的配置
    拓展:正则表达式-常用函数
  • 原文地址:https://www.cnblogs.com/xushaoxin/p/3258757.html
Copyright © 2020-2023  润新知