我不能强调这一点 - 设计原因.
在C++中,您可以使用类(类型)引用或对象(实例)引用获取静态元素.在C#中只有类型引用.我在C#中写的越多,它引起的问题就越多 - 只有片刻(一次又一次)我所拥有的只是对象,并且为了通过创建来避免缺少类型(因此访问静态元素)的问题常规元素,它将值来回传递给静态元素.
可以说,在一个类中创建常规(非静态)元素作为静态元素的代理是很小的代价,但我不知道我实际支付的是什么.对我来说,负担是显而易见的,不是关键的,而是烦人的,那么有什么好处呢?
有什么设计原因,在C#中你不能引用对象的静态元素(当然是从外部)?
public class Foo
{
public static readonly string Name = "name";
}
...
Foo foo = new Foo();
Run Code Online (Sandbox Code Playgroud)
现在考虑"Foo.Name"对"foo.Name";
对我来说,最常用的类之一是用于枚举的关联数组(我的自定义类) - AssocEnum.它就像词典,但所有键都是预填充的.最重要的是,我有像EnumBit(这是AssocEnum)和EnumNames(它是AssocEnum)这样的类.与Dictionary不同,每个给定枚举的实例都具有相同的Keys属性.这意味着你可以获得AssocEnum类型的密钥及其实例.
困扰我的是我必须引入两个属性TypeKeys(用于类)和Keys(例如 - 它只是TypeKeys的代理),因为我无法调用静态TypeKeys作为AssocEnum的例子.
IMO这里的"设计理由"在某种程度上与使意图明显有关.这是一个经典的例子:
Thread someOtherThread = GetAnotherThread();
someOtherThread.Sleep();
Run Code Online (Sandbox Code Playgroud)
现在; 哪个线程刚睡觉?Thread.Sleep()是一种静态方法; 它只会影响当前的线程.但是我们的代码建议(非常错误地)我们调用了与特定实例(someOtherThread)相关的方法.
完全有可能设计语言以允许它解析静态方法; 这是微不足道的 - 所以它绝对是一个有意的设计选择,而不是技术限制.
另一个例子:
Control someControl = GetSomeRandomControl();
someControl.CheckForIllegalCrossThreadCalls = false;
Run Code Online (Sandbox Code Playgroud)
我们的代码建议我们进行了更改以禁用特定对象的跨线程检查; 但这是不正确的.实际上我们已经影响了所有控件,因为它CheckForIllegalCrossThreadCalls是一个静态成员.
从而:
Thread.Sleep():
Run Code Online (Sandbox Code Playgroud)
和:
Control.CheckForIllegalCrossThreadCalls = false;
Run Code Online (Sandbox Code Playgroud)
在表达他们所做的事情方面更清楚.