有没有一种很好的方法来处理C#中泛型类型的私有静态字段?

时间:2017-03-23 01:05:20

标签: c# generics static

我试图找出一种方法,可以利用通用private中的static class字段。这是显而易见的方法(fiddle)。它不会编译,因为Field无法访问BaseChild,理想情况下我不希望它可以在那里访问:

public class Base<T>
{
    private static readonly string Field = "field";

    public Base()
    {
        Console.WriteLine(Field);
    }
}

public class BaseChild : Base<string>
{
    public BaseChild()
    {
        Console.WriteLine(Field);
    }
}

此解决方案的问题在于每种通用类型都有不同的Field,而不是在它们之间共享。

我已经看到了这个answer,其中说JetBrains建议跨越泛型类型的static字段的解决方案:

  

如果需要在具有不同泛型参数的实例之间共享静态字段,请定义一个非泛型基类来存储静态成员,然后将您的泛型类型设置为从此类型继承。

对于您希望在任何子级public中共享protected课程中的staticbase class个字段的情况,这是有意义的像这个例子(fiddle):

public abstract class Base
{
    protected static readonly string Field = "field";
}

public class Base<T> : Base
{
    public Base()
    {
        Console.WriteLine(Field);
    }
}

public class BaseChild : Base<string>
{
    public BaseChild()
    {
        Console.WriteLine(Field);
    }
}

但是,您希望使用private static字段的情况如何?我猜这是不可能的,因为private只表示class可以访问它,我认为因为通用class实际上只是一个模板来创建一个class,任何private字段只能由每个class共享,而不能在模板创建的所有类中共享。

我是否必须将private字段放在泛型类(示例1)中并接受它作为我想要的至少一个可行的解决方案,还是有另一种方法可以实现这一点?

3 个答案:

答案 0 :(得分:1)

首先关闭 - private正在完成它的工作:限制只访问它所声明的类型。请记住,泛型类型的实例化都是不同的类型。你不应该想要解决这个问题。

如果我正确理解了您的问题,那么您可以使用protected以及更高级别的继承来完成您想要的任务:

class EvenMoreBase
{
    protected static readonly string Field = "field";
}

class Base<T> : EvenMoreBase
{
    public Base()
    {
        Console.WriteLine(Field);
    }
}

class BaseChild : Base<string>
{
    public BaseChild()
    {
    Console.WriteLine(Field);
    }
}

现在,您的每个Base<T>都会共享Field的相同实例。

答案 1 :(得分:1)

您在基类中对private的想法是正确的。它是静态的还是没有区别。

这是一个小例子:

using System;

public class Program
{
    public static void Main()
    {
        Bar b = new Bar(); // Prints "Foo"
        // Console.WriteLine(Foo.BaseField); // Compile error
    }
}

public class Foo 
{
    protected static readonly string BaseeField = "Foo";
}

public class Bar : Foo
{
    public Bar()
    {
        Console.WriteLine(Foo.BaseeField);
    }
}

如果您只想让您的孩子能够访问它,则将其标记为受保护非常有用。留下static就是如何为基础Foo类的所有孩子保留一个实例。

答案 2 :(得分:0)

这是我想出的东西,我认为实际上做的比我在问题中提出的最初的例子更好。它在所有泛型类型中共享一个静态字段,并且无法从Base泛型类的子节点访问它。

public static class Base
{
    private static string Field = "field";

    public class Base2<T>
    {
        public Base2()
        {
            // Field is accessible here, but is the same across all generic classes
            Console.WriteLine(Field);
        }
    }
}

public class BaseChild : Base.Base2<string>
{
    public BaseChild()
    {
        //Field is not accessible here, and I don't really want it to be
        //Console.WriteLine(Field);
    }
}