或者为什么以下内容是不可能的:
class Material
{
class Keys
{
...
}
Material.Keys Keys { get; set; } // Illegal
}
我没有看到任何可能的歧义。通过实例访问时,返回属性。以静态方式访问时,返回类。或者我有什么遗漏吗?
我不是在要求“修复”(我知道我可以将其命名为MaterialKeys之类的其他名称),而是想了解这个限制背后的技术原因。
或者为什么以下内容是不可能的:
class Material
{
class Keys
{
...
}
Material.Keys Keys { get; set; } // Illegal
}
我没有看到任何可能的歧义。通过实例访问时,返回属性。以静态方式访问时,返回类。或者我有什么遗漏吗?
我不是在要求“修复”(我知道我可以将其命名为MaterialKeys之类的其他名称),而是想了解这个限制背后的技术原因。
但想象一下你有这样的代码:
class Material
{
class Keys
{
...
}
static Material.Keys Keys = new Keys();
}
现在两者都处于"static"作用域。现在,编译器能够在所有情况下消除歧义吗?如果不能,则不允许这样做。
我想可能会对静态字段/属性/方法进行消歧义,而不是针对实例成员。或者反过来。如果是这种情况,您希望语言规范允许实例成员与内部类具有相同的名称,但禁止静态成员吗?这只会令人困惑。
但是,让成员与内部类的名称匹配本身就很令人困惑。
Material.Keys
类和 Material.Keys
静态成员。这基本上是这种机制的破坏者。我想说的是,如果遇到这种情况,应该考虑是否在命名时尽可能描述清楚,例如使用 KeyCollection
而不是 Keys
。 - crushenum ReportType
的枚举。现在我可能想要一个名为 ReportType 类型为 "enum ReportType" 的属性。我不想在此类之外混杂该枚举,因为我想将其称为 Foo.ReportType.MyFancyReport
。创建模型类时这些情况非常普遍。 - arviman您说过,
在实例访问时返回属性。在静态访问时返回类。
但是如果您只是在 Material
中的某个地方说 Keys
,这是静态访问还是实例访问?这是指属性 Keys
还是嵌套类型 Keys
?实际上是不明确的。
例如,
class Material
{
class Keys
{
public static int Length;
}
string Keys { get; set; }
public void Process()
{
// Does this refer to string.Length (via property Keys)
// or Material.Keys.Length? It actually refers to both.
Console.WriteLine(Keys.Length);
}
}
正如评论中指出的那样,这并不是整个故事,但几乎是。可以有一个名为Color
且类型为Color
的属性,而且没有任何冲突:
public Color Color { get; set; }
Color.FromName(...) // refers to static method on the type ‘Color’
Color.ToString() // refers to instance method on the property’s value
public class MyType { public string FromName(string name) { return null; } }
public MyType Color;
Color.FromName(...) // unambiguously refers to MyType::FromName(string)
// via the property Color
在您的示例中并不容易-嵌套类 Keys
和属性 Keys
在同一范围内(具有相同的声明类型)。你如何决定给哪一个优先级?即使您决定给其中之一优先级,这也只是微不足道的有用,因为您仍然只能拥有两个相同名称的东西,而一个必须是静态的,另一个必须是实例。
Material.Keys
也引用了你的类型为 Material.Keys
的成员变量,因此出现了问题。 - Michael Shimmins我的答案从与其他问题略有不同的角度回答了这个问题。在 C# 语言规范中,以下两个语句:
The same identifier may not be used in different definitions within one scope
并且
The same identifier may not be used in different definitions within one scope, unless it is probably impossible for any ambiguity to arise when the identifier is used
第一段要简单得多。
在语言设计中,简洁是一个关键目标,因为简单的语言更容易让编译器和解释器作者实现,更容易生成和操作工具,更容易让初学者学习,也更容易让程序员理解。在考虑任何语言特性时,该特性增加的复杂性应该被视为负面因素,并且必须通过至少同等量的有用性来平衡。正如您自己所说,允许这样做不会添加任何真正的功能(因为它很容易避开),因此在C#规范中包含它没有令人信服的理由。
Keys
是 Material
的成员,而属性 Keys
也是其成员。你有两个名为 Keys
的成员。public class Bar
{
private bool Foo { get; set; }
private string Foo { get; set; }
}
Foo
时,你是想访问哪一个?public class Material : Keys
{
private Keys K { get; set; }
}
public class Keys
{
}
这个功能可以正常工作,但可能不是你想要的。
Members
内部访问Keys
时呢?它是静态的还是成员的?public Material() { Keys. // 哪一个? }
- Michael Shimminsnew Material() { Keys }
明显是实例化的一个。 - Lazlo