属性应与其类型具有相同的名称吗?


70

我有时看过这样写的代码:

public class B1
{
}

public class B2
{
    private B1 b1;

    public B1 B1
    {
        get { return b1; }
        set { b1 = value; }
    }
}

即类B2具有一个名为“ B1”的属性,该属性也属于“ B1”类型。

我的直觉告诉我这不是一个好主意,但是是否有任何技术上的原因为什么您应该避免给与该类同名的属性呢?

(以防万一,我正在使用.net 2.0)。


我相信.NET框架设计指南也建议使用此命名约定。
NotDan

1
哪种命名约定-称它们为同一事物,还是更改区分大小写?
niico

Answers:


63

没关系。典型的例子是

public Background {
    public Color Color { get; set; }
}

这里有一些罕见的问题(紧急情况),但不足以保证避免使用此设备。坦白说,我发现该设备非常有用。我不喜欢无法执行以下操作:

class Ticker { ... }


public StockQuote {
    public Ticker Ticker { get; set; }
}

我不想说Ticker StockTicker或其他Ticker ThisTicker


13
class A { public static void Method(int i) { } public void Method(object o) { } }class B { A A { get; set; } public B() { A = new A(); A.Method(0); } }。是A.Method调用名为的静态方法Method还是调用名为的实例方法Method?(在C#事实证明,它会调用静态方法。但是,如果你更换0A.Method(0)"Hello, world!",它会调用实例方法。请注意,IntelliSense不挑这件事,并突出AA.Method("Hello, world!")蓝色,好像它是静态的方法。)
杰森

2
但这只是要指出的是,在某些情况下,使用这种模式的代码的意图不是很明确(当然,根据语言规范,总是有明确的解释)。
杰森

1
@jason Properties我同意,但是反对为什么?您是否不想将静态(类)方法调用与实例调用区分开?如果您有一个对象,我认为没有理由A = new A(),那就去做a = new A()。它不再是一个,而是更加清晰。您的极端情况涉及对象,而不是属性。但是,您关闭了有关对象的问题。在VB中,当对象和类的名称相同时,智能感知和重命名不区分类引用和实例引用。但是重命名与类型相同的属性是没有问题的。
詹森·S,

@Jason请参见此问题,以获取与对象名称相同的VB项目中的重命名有关的问题。但这并不适用于性能,但我对命名对象的问题同他们的阶级,被关闭,因为这一个的副本。
詹森·S

@jason您的边缘情况也意味着,如果您重命名对象的引用,AA=new A()a例如,A.Method("Hello, world!")将不改名,导致NullReferenceException在运行时。不给对象命名与类相同的另一个原因,但这不是属性的问题!用与返回类型相同的名称重命名该属性不是问题。
詹森·S

17

微软的命名指南会员状态:

考虑给一个属性与其类型相同的名称。

当您具有一个强类型为枚举的属性时,该属性的名称可以与枚举的名称相同。例如,如果您有一个名为的枚举 CacheLevel,则返回其值之一的属性也可以命名为CacheLevel

尽管我承认他们只是针对Enums还是针对一般物业推荐这样做还是有点含糊。


12

我只能想到一个缺点。如果您想做这样的事情:

public class B1
{
        public static void MyFunc(){ ; }
}

public class B2
{
        private B1 b1;

        public B1 B1
        {
                get { return b1; }
                set { b1 = value; }
        }

        public void Foo(){
                B1.MyFunc();
        }
}

您必须改为使用:

MyNamespace.B1.MyFunc();

一个很好的例子是Winforms编程中的常用用法,其中System.Windows.Forms.Cursor类与System.Windows.Forms.Form.Cursor属性重叠,因此您的表单事件必须使用完整的命名空间访问静态成员。 。


11

就在今天,埃里克(Eric)在博客上谈到了“颜色”问题。

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

就个人而言,如果可能,我会避免这样做。


4
为什么?我看不出有什么害处。
史蒂文·苏迪特

1
@StevenSudit IMO它为程序员增加了复杂性(毕竟,您需要阅读该文章以了解正在发生的事情),而且我们程序员知道这是多么糟糕和容易出错。我也会避免的。
2012年

3
他的文章实际上表明,拥有相同名称的静态成员和实例成员是愚蠢的。我希望任何程序员都可以避免。注意这个关键句子“在实际情况下,实例和静态方法通常具有不同的名称”。请注意,所有这些问题都是由于他声明了static M(instance)而引起的M。的讨论Color Color只是表明,结合 Color Colorstatic MM使问题变得更糟。所以不要做原始的白痴。
制造商史蒂夫(Steve)

4

另一个陷阱是内部类型。

我一直都遇到这个问题:

public class Car {
    public enum Make {
        Chevy,
        Ford
    };

    // No good, need to pull Make out of the class or create
    // a name that isn't exactly what you want
    public Make Make {
        get; set;
    }
}

5
这就是为什么我将枚举名称复数的原因。有几种可能Makes的汽车,但这种汽车只有一种Make。它并不总是读得最好的,但我认为枚举是可能列表Makes
Hand-E-Food

3

它没有特定的技术问题。它可能会损害或提高可读性。实际上,某些Microsoft库具有这些类型的属性(特别是对于enum属性,这通常是有意义的)。


2

这种常见模式是我this在引用类中的实例成员时始终使用的原因之一。例如总是

this.SomeMethod(this.SomeProperty);

永不

SomeMethod(SomeProperty);

在大多数情况下,没有任何实际的歧义,但是我发现它有助于弄清楚事情。另外,您现在知道属性/方法的定义位置。


1

当一个属性的名称和它的类型相同时,显然会造成一些混乱,但是除此之外,这并不是真正的问题。

如果名称有意义,通常最好让名称和类型相同。如果您能想到一个更好的名字,那么您当然应该使用它,但是您不应该为了避免这种情况而尝试不惜任何代价组成一个名字。


0

除事例外,我给事物起相同的名称:我的方法和属性为“ lowerCase”;因此,我不会遇到MiffTheFox所遇到的问题。

public class B1
{
    public static void myFunc(){ ; }
}

public class B2
{
    private B1 m_b1;

    public B1 b1
    {
        get { return m_b1; }
        set { m_b1 = value; }
    }

    public void Foo()
    {
        B1.myFunc(); //this is Ok, no need to use namespace
    }
}

因此,对我来说,m_b1成员数据,b1属性(或局部变量或参数),B1类的名称都是。


5
不幸的是,对于“属性和方法”使用小写字母会与公认的C#命名准则直接冲突。
Timothy Walters,2009年

是。IMO,它们是次等准则,您不同意吗?为什么会成为?
ChrisW

1
在最大程度地提高清晰度/最小化误解方面进行权衡。考虑一个典型的代码文件。计算所有类名称,成员名称和局部变量名称的所有外观。您会发现类名称仅占命名项总外观的一小部分。因此,您的选择将“小写”分配给绝大多数名称显示。因此,为区分“类别”和“非类别”分配了很高的价值。没问题,但是推荐的样式将“本地”与“非本地”区分开。也许以相反的方式失去平衡...
ToolmakerSteve18年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.