2010-10-06 67 views
7

我从来没有真正质疑过这一点,直到现在。我有与一些领域的输入模式,我想通过输入模型呈现属性的字符串名称,这样我的网格可以使用它们:为什么类没有静态或常量属性和同名的实例属性?

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public string Description { get;set; } 

    public const string Code = "Code"; 
} 

显然,这给出了错误:

The type 'SomeGridRow' already contains a definition for 'Code'

为什么CLR不能处理两个在我眼中是分开的名字?

string code = gridRow.Code;   // Actual member from instantiated class 
string codeField = SomeGridRow.Code; // Static/Const 

我现在只用叫我输入内Fields现在一个子类,所以我可以使用SomeGridRow.Fields.Code。这有点乱,但它的工作原理。

回答

7

因为你也可以以同样的方式访问静态(或在此情况下,非实例)的属性(同一类中),这将是一个有点混乱,例如:

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public const string Code = "Code"; 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

因为这两个:

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

这:

public class SomeGridRow 
{ 
    public const string Code = "Code"; 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

是访问性能的有效途径,ST原子或不是。它不回答“为什么我不能?”问题,但更多的是为什么它不被允许......这将是非常模糊的国际海事组织。

+0

Aye,I sup当这样拼写出来时,这很明显。我总是把静态成员视为理所当然的使用他们的实际类名进行访问。作为我工作的部分编码标准。 – GenericTypeTea 2010-10-06 09:45:19

+1

@GenericTypeTea - 这是一个很好的标准,在课堂上是我认为最暧昧的地方,也许它永远不会被允许这种方式......但我认为它最终的方式可能是最容易混淆的妥协。 – 2010-10-06 09:47:22

+0

我同意。这是另一种尺寸不适合所有人的情况......这真的不是什么大问题。我只是挑剔。我只是厌恶嵌套类。 – GenericTypeTea 2010-10-06 09:50:03

3

它可能会,但C#的设计者想避免可能来自这种语言功能的使用(滥用?)的歧义。

这样的代码最终会让用户感到困惑和不明确(我是想要实例还是静态方法调用?哪一个是正确的?)。

+0

我坚持的标准总是规定静态成员必须通过其静态名称。''Foo'永远都是'TheStaticClass.Foo'。所以歧义不会影响到我,真是太遗憾了!我宁愿有潜在的(但是控制的)歧义而不是嵌套类。 – GenericTypeTea 2010-10-06 09:43:12

+0

@GenericTypeTea - 如果只有MS为你写了C#并且只有你) – Oded 2010-10-06 09:44:32

+0

好吧,他们应该.Visual Studios 2010 GenericTypeTea edition!我会买它:) – GenericTypeTea 2010-10-06 09:45:59

1

除了已经提出的关于歧义的观点之外,我会说在这种情况下需要重新命名这个命名。

如果在同一个上下文中具有完全相同名称的两个变量/字段,即类但对我来说不同的值更像是一个命名问题。

如果它们完全相同,则不需要2个字段。

如果它们略有不同,则应该有更准确的名称。

+0

instantiatedClass.Code =='实际值'。 TheClass.Code =='字段的名称'传递到网格的列数据源。我不喜欢坐在视图中的字符串值。唯一的选择是使用Lambda表达式并使用反射来获取MethodName。 – GenericTypeTea 2010-10-06 09:48:41

+0

@GenericTypeTea - 也许它只是我做这件事的方式,但TheClass.Code对我来说更加准确,因为TheClass.CodeColumnName代表列名,并且不会与theObject.Code混淆 - 代表值在代码栏中。在这种情况下,我会认为这两个变量是完全不同的,因此有不同的名称。至少,以“代码”作为他们的名字都是误导。恐怕我不太清楚名称之间的联系以及如何在你的lambdas中使用它们。 – InSane 2010-10-06 09:54:08

0

在一些语法类似的其他语言中,可以通过实例访问静态成员。所以你可以访问string.Empty"abc".Empty

C#不允许这样做(虽然它的确可以从类或派生类中进行排序,因为您可以省略静态成员的类名称,并且可以省略实例成员的this),主要是为了避免混乱(我发现它比混淆tbh更方便,但这只是我,我喜欢开关掉落,所以我知道什么)。

在引入更严格的规则以减少歧义之后,在允许更多的背面允许新的宽松规则会适得其反。想想有多少“为什么我必须使用this属性X但不是属性Y?“如果允许的话,SO会有的问题(我们必须强制this与属性X清楚我们的意思是实例成员)