直到现在我才真正质疑过这个问题。我有一个包含许多字段的输入模型,我想通过输入模型显示属性的字符串名称,以便我的网格可以使用它们:
public class SomeGridRow
{
public string Code { get;set; }
public string Description { get;set; }
public const string Code = "Code";
}
显然,这会产生错误:
类型'SomeGridRow'已经存在 包含'Code'的定义
为什么CLR无法应对两个同名的属性,在我看来,这两个属性是分开的?
string code = gridRow.Code; // Actual member from instantiated class
string codeField = SomeGridRow.Code; // Static/Const
我现在只在输入中使用名为Fields
的子类,因此我可以使用SomeGridRow.Fields.Code
。它有点乱,但它确实有效。
答案 0 :(得分: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?
}
}
是访问属性的有效方法,静态与否。它没有回答“为什么我不能?”问题,但更多的是为什么它不被允许......这将是太模糊的IMO。
答案 1 :(得分:3)
它可能会,但C#的设计者希望避免可能来自语言特征的这种使用(滥用?)的含糊不清。
这样的代码最终会让用户感到困惑和模棱两可(我想要实例或静态方法调用吗?哪一个是对的?)。
答案 2 :(得分:1)
除了已经提出的关于模棱两可的观点之外,我想说在这种情况下需要重新审视命名。
如果两个变量/字段在同一个上下文中具有完全相同的名称,即类但对我来说不同的值听起来更像是命名问题。
如果它们完全相同,则不需要2个字段。
如果它们略有不同,你应该有更准确的名字。
答案 3 :(得分:0)
在其他一些语法相似的语言中,可以通过实例访问静态成员。因此,您可以同时访问string.Empty
和"abc".Empty
。
C#不允许这样做(尽管它确实来自类或派生类,因为你可以省略静态成员的类名,并且可以省略实例成员的this
),主要是为了避免混淆(我觉得它比混乱更方便,但这只是我,我喜欢切换掉落,所以我知道什么)。
引入更严格的规则以减少歧义,允许更多更宽松的规则允许更宽松的规则会适得其反。想想有多少“为什么我必须使用this
属性X而不是属性Y?”问题如果允许的话会有所帮助(我们必须强制this
使用属性X来清楚我们的实例成员。)