命名规范

夙愿已清 提交于 2020-03-25 14:52:54

建议126.用名词和名词组给类型命名

类型对应着现实世界中的实际对象。对象在语言中意味着它是一个名词。所以,类型也应该以名词或名词词组去命名。

类型定义了属性和行为。虽然它包含行为,但不是行为本身。所以,下面的一些命名对于类型来说是好的命名:

OrderProcessor

ScoreManager

CourseRepository

UserControl

DomainService

相应的,如下面的类型名称则被认为是不好的典范:

OrderProcess

ScoreManage

ControlInit

DomainProvide

动词类的命名更像是类型内部的一个行为,而不是类型本身。

建议127.用形容词组给接口命名

接口规范的是“Can do”,也就是说,它规范的是类型可以具有哪些行为。所以,接口的命名应该是一个形容词,如:

IDisposable表示可以被释放

IEnumerable表示类型含有Items,可以被迭代。

 

建议128:考虑让派生类的名字以基类名字作为后缀

派生类的名字可以考虑以基类名字作为后缀。这带来的好处是,从类型的名字上我们就知道它包含在哪一个继承体系中。

Exception及其子类就是这样一个典型的例子。所有的异常都应该继承自System.Exception,而所有的异常都应该命名为CustomedException。如果在VS中输入Exception,再按Tab键,会自动生成如下代码:

  [Serializable]
    public class MyException : Exception
    {
        public MyException()
        {
        }

        public MyException(string message) : base(message)
        {
        }

        public MyException(string message, Exception inner) : base(message, inner)
        {
        }

        protected MyException(SerializationInfo info,StreamingContext context) : base(info, context)
        {
        }
    }

从这里我们可以看出,微软支持让派生类的名字以基类名字作为后缀。

在FCL中,这类常用的例子还有Attribute、EventArgs等。

建议129:泛型类型参数要以T作为前缀

作为一种约定,泛型类型的参数要以T作为前缀。如委托声明:

Action<T1,T2>

其中,泛型类型参数名不应该处理成:

Action<Arg1,Arg2>

当然,这仅仅是一种习惯,若果使用第二种命名方式,编译器并不会报错,但是作为调用者,也许不能意识到这里是一个泛型类型参数。这个问题在为类型指定泛型的时候尤为明显,因为为类型指定泛型类型参数的声明不会出现在公开的接口中。

建议130:以复数命名枚举类型,以单数命名枚举元素

枚举类型应该具有复数形式,它表达的是将一组相关元素组合起来的语义。比如:

enum Week
    {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday
    }

在这里,Week对于星期几来说,具备复数含义。如果我们将Week修改为Day,那么调用的代码会变成如下形式:

Day.Monday

它不会比下面的代码更简洁了:

Week.Monday

 

建议131:用PascalCasing命名公开元素

开放给调用者的属性、字段和方法都应该采用PascalCasing命名方法,比如:

    class Person
    {
        public string FirstName;
        public string LastName;

        public string Name
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }

        public string GetName()
        {
            return Name;
        }
    }

这样,调用者在调用的代码看起来如下:

person.Name

如果我们不注意这样的命名规则,让调用方的代码看起像这样:

person.name

我们首先会怀疑name是什么类型,其次也会怀疑其可访问性。

 

建议132:考虑用类名作为属性名

一般来说,若果属性对应一个类型,应该直接用类型名命名属性名。如下:

class Person
{
     public Company Company { get; set; }
}

class Company
{
        //省略
}

没有必要为属性名指定另外的名字,如:

public Company TheCompany{get;set;}

当然,除非我们的类型当中有多个Company类型的属性,这样就必须为我们的属性重构成不同的命名,如:

 class Person
 {
     public Company Company { get; set; }
     public Company SecondCompany { get; set; }
 }

建议133:用camelCasing命名私有字段和局部变量

私有变量和局部变量只对本类型负责,它们在命名方式也采用和开放的属性及字段不同的方法。camelCasing很适合这类命名。

camelCasing和PascalCasing的区别是它的首字母是小写的。之所以要采用这两种不同的命名规则,是为了便于开发者自己快速地区分它们。例如:

    class Person
    {
        private string firstName;
        private string lastName;

        public string Name
        {
            get { return string.Format("{0} {1}", firstName, lastName); }
        }

        private int doSomething(int a, int b)
        {
            int iTemp = 10;
            return a + b + iTemp;
        }
    }

我们可以看到,所有私有字段,包括方法的参数及局部变量全部遵循首字母小写的cameCasing规则。一旦脱离了这种规则,在编码过程中很容易给自己造成混淆。

建议134:有条件地使用前缀

 在.NET的设计规范中,不建议使用前缀。但是,即便是微软自己依然广泛的使用着前缀。

最典型的前缀是m_,这种命名一方面是考虑到历史沿革中的习惯问题,另一方面也许我们确实有必要这么做。

在一个不是很庞大的类型中,我们确实不应该使用任何前缀。各类设计规范也总建议我们保持一个娇小的类型,但是往往事与愿违,大类型常常存在。以Task为例,它有2000多行代码。在这种类型中,如果不使用前缀,我们很难区分一个类型是实例变量还是静态变量,或者是一个const变量。

最常见的做法是:

前缀m_,表示这是一个实例变量。

前置s_,表示这是一个静态变量。

注意,有时候,如果类型只有实例变量或者只有静态变量,我们也直接使用前缀,以区别该变量不是一个局部变量。

而const变量则常常使用名词加下划线的表示方法,如:

internal const int TASK_STATE_CANCELED=0x400000;

记住,前缀仅限于此,匈牙利命名法中的其他规则(如用类型名做前缀)是绝对要禁止的。

一个正确使用前缀的示例如下:

    class SampleClass
    {
        private static int s_price;
        private int m_price;
        private const int BASED_PRICE = 1000;

        public static void SetStaticField(int price)
        {
            s_price = price;
        }

        public void SetClassField(int price)
        {
            m_price = price;
        }
    }

    class SampleClass2
    {
        private int _price;

        public void SetPrice(int price)
        {
            _price = price;
        }
    }

建议140:使用默认的访问修饰符

类或接口的默认修饰符是 internal(程序集内可见),类成员的默认修饰符为private;

有意忽略默认访问修饰符,除了可以减少代码的数量外,也有助于我们熟悉代码的默认行为。

 

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!