当属性位于基类中时,如何访问子类中的静态属性?

2 c# inheritance

比方说我有:

public class Fruit
{

    public static List<String> Suppliers { get; protected set; }

    static Fruit()
    {
        Suppliers = new List<String>();
        Suppliers.Add("Company A");
    }

}

public class Banana : Fruit
{

    static Banana()
    {
        Suppliers.Add("Company B");
    }

}
Run Code Online (Sandbox Code Playgroud)

如果我只是在调用代码中执行此操作:

foreach(String supplier in Banana.Suppliers)
    Console.WriteLine(supplier);
Run Code Online (Sandbox Code Playgroud)

我明白了:

  • 公司A.

如果我这样做:

Banana b = new Banana();
foreach(String supplier in Banana.Suppliers)
    Console.WriteLine(supplier);
Run Code Online (Sandbox Code Playgroud)

我得到了(期望的结果):

  • 公司A.
  • 公司B.

编辑: 阅读回复后我明白这不会奏效.

我在生产代码中想要的是一个对象类型共有的值列表,我想根据子类型动态地将不同的值添加到该字符串列表中.(上下文是LDAP - 所有条目都有objectClass = top,所有用户对象都有objectClass = user,top,organizationPerson,person).猜猜如果没有人有更好的建议,我必须在每个子类中使用一个接口或不同的列表?

Jon*_*eet 13

首先,访问Banana.Suppliers是误导性的.它总会产生与访问Apple.Suppliers等相同的结果- 您只有一个供应商集合.

基本上,每次访问Banana.Suppliers编译器时都会调用Fruit.Suppliers:这就是为什么只是调用Banana.Suppliers不会触发添加香蕉供应商的静态构造函数.

您在创建香蕉后只看到香蕉静态构造函数中添加的供应商的原因是强制静态构造函数运行.你可以做任何其他迫使静态初始化程序运行的东西,你会得到相同的结果.一个例子是在Banana自身内部调用静态方法.

现在,我强烈怀疑您遇到了一个重大问题,即您将使用所有类型的相同供应商.显然,这不是您的真实代码,最佳解决方案将取决于您希望实际代码执行的操作.泛型可以使用类型参数为您提供有效的"每类型"静态变量:Foo<Banana>.StaticProperty并且Foo<Apple>.StaticProperty实际上将是不同的,假设StaticProperty是在声明中Foo<T>.

编辑:关于你的编辑,我建议避免在这里使用静态.可能为每种类型创建一个工厂(实现可能是通用的接口).请注意,如果可以为每种类型创建包含所有相关项的相应实例,则可以避免为每个子类型创建单独的工厂类型.

我们确实需要看到更多可以肯定的例子,但总的来说,我发现你拥有的静态数据越少,你的设计就越可测试,你遇到的问题就越少:)


hea*_*vyd 6

您看到的结果是由静态构造函数的工作方式引起的.CLR实际上并不执行使用第一个实例的静态构造函数util,这就是为什么你只在第二个例子中得到所需的结果.有关详细信息,请参阅MSDN.