C# 为什么一个类不能有一个静态或常量属性和一个同名的实例属性?

C# 为什么一个类不能有一个静态或常量属性和一个同名的实例属性?,c#,C#,直到现在我才真正质疑过这一点。我有一个包含许多字段的输入模型,我想通过输入模型显示属性的字符串名称,以便我的网格可以使用它们: public class SomeGridRow { public string Code { get;set; } public string Description { get;set; } public const string Code = "Code"; } 显然,这会产生错误: 类型“SomeGridRow”已存在 包含“代码”的

直到现在我才真正质疑过这一点。我有一个包含许多字段的输入模型,我想通过输入模型显示属性的字符串名称,以便我的网格可以使用它们:

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

    public const string Code = "Code";
}
显然,这会产生错误:

类型“SomeGridRow”已存在 包含“代码”的定义

为什么CLR不能处理两个在我看来是分开的同名属性

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

我现在只在输入中使用名为
Fields
的子类,因此我可以使用
SomeGridRow.Fields.code
。这有点混乱,但它可以工作。

可能可以,但C#的设计者希望避免由于使用(滥用)语言功能而产生的歧义


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

因为您也可以以相同的方式(在同一个类中)访问静态(或者在本例中是非实例)属性,这会有点困惑,例如:

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?
  }
}

是访问属性(静态或非静态)的有效方法。它并没有回答“为什么我不能?”的问题,但更多的是为什么它不被允许……在我看来,它太模糊了。

除了已经提出的关于模糊性的观点外,我想说,在这种情况下,命名需要重新确定

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

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


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

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

C#不允许这样做(虽然它在类或派生类内部允许这样做,因为您可以省略静态成员的类名,也可以省略实例成员的
this
),主要是为了避免混淆(我发现它比混淆tbh更方便,但这只是我自己,我也喜欢切换失败,所以我知道什么)


在引入了一个更严格的规则以减少歧义之后,如果在其背后允许一个新的更宽松的规则以允许更多的歧义,那将适得其反。想想有多少“为什么我必须对属性X使用
this
,而不是属性Y?”这样的问题,如果允许的话(我们必须对属性X强制
this
,以明确我们指的是实例成员)。

我遵守的标准总是规定静态成员必须以其静态名称引用。也就是说,
Foo
始终是staticclass.Foo。所以模棱两可不是一个会影响我的问题。真可惜!我宁愿有潜在的(但可控的)歧义,而不是嵌套的类。@GenericTypeTea-如果MS为您和您编写C#就好了嗯,他们应该这样做。Visual Studio 2010 GenericTypeTea版!我会买:)@GenericTypeTea-是的……但是你如何说服其他人安装GTT.Net可再发行版本呢?:)@尼克·克雷弗-加牛奶和饼干。明显地是的,我想这是很明显的。我总是想当然地认为静态成员是使用它们的实际类名访问的。我工作的部分编码标准。@GenericTypeTea-这是一个很好的标准,在类内部是我认为最模糊的地方,也许它不应该被允许这样做…但我认为它最终的方式可能是最容易混淆的折衷。我同意。这是另一个大小不一的箱子。。。这真的不是什么大问题。我只是太挑剔了。我只是讨厌嵌套类。实例化类。代码=='实际值'。class.Code==“要传递到网格的列数据源中的字段名称”。我不喜欢视图中的字符串值。唯一的替代方法是使用Lambda表达式并使用反射来获取方法名。@GenericTypeTea-也许这只是我的方法,但是class.Code对我来说更像class.CodeColumnName,因为它代表列名,并且不要与object.Code混淆,后者代表代码中的值专栏。在这种情况下,我会认为这两个变量是完全不同的,因此有不同的名称。至少对我来说,用“代码”作为两者的名称是有误导性的。恐怕我不太明白这些名字和你在lambdas中如何使用它们之间的联系。。。