通过泛型继承实现静态成员可访问性

时间:2018-03-16 19:21:33

标签: c# generics inheritance static protected

我最近提出了一些相当时髦的单例工作,并发现我可以使用相同的继承类型从任何唯一的继承类型访问受保护的静态成员,其中使用了泛型。我所谈论的一个例子如下:

public abstract class Class<T>
{
    protected static int number = 5;

    public void Print()
    {
        Console.WriteLine(number);
    }
}

public class ClassA : Class<ClassA>
{
}

public class ClassB : Class<ClassB>
{
    public ClassB()
    {
        number = 1;
    }
}

public class ClassC : Class<ClassC>
{
    public ClassC()
    {
        number = ClassA.number;//I don't want to be able to see "number"
    }
}

由于泛型在这里使用,每个唯一的继承类型都有自己的&#34;数字&#34; (这就是我想要的)。但我不喜欢我可以访问&#34;数字&#34;在使用泛型时从其他类型继承相同的基类型。有没有办法来解决这个问题?还有为什么会发生这种情况(我理解为什么它会在没有泛型的情况下继承而发生,但它在仿制药中发生的情况似乎并不正确)?

2 个答案:

答案 0 :(得分:1)

  

我不喜欢我可以访问&#34;号码&#34;在使用泛型时从其他类继承相同的基类。有办法解决这个问题吗?

唯一真正的解决方法是为每个类声明单独的private static变量。这将使您无法从任何其他类类型中查看一个类类型中的数字变量。

public abstract class Class<T>
{
    private static int number = 5;

    public void Print()
    {
        Console.WriteLine(number);
    }
}

public class ClassA : Class<ClassA>
{
}

public class ClassB : Class<ClassB>
{
    private static int number;

    public ClassB()
    {
        number = 1;
    }
}

public class ClassC : Class<ClassC>
{
    private static int number;

    public ClassC()
    {
        number = 123; // Cannot see ClassA.number because it is private to `Class<T>`
    }
}

副作用是由声明变量protected static并将其与继承一起使用引起的。目前还不清楚为什么当你所追求的行为属于private static字段时,你会尝试这样做。

答案 1 :(得分:-3)

您可以使用private修饰符使静态成员对后代不可见。仅在您希望后代能够访问它时才使用protected。通用与非通用没有区别。

public abstract class Class<T>
{
    private static int number = 5;  //Private now

    public void Print()
    {
        Console.WriteLine(number);  //Works
    }
}

public class ClassA : Class<ClassA>
{
    //No number
}

public class ClassB : Class<ClassB>
{
    public ClassB()
    {
        number = 1;  //Will not compile
    }
}

public class ClassC : Class<ClassC>
{
    public ClassC()
    {
        number = ClassA.number;//Will not compile
    }
}

如果您希望静态变量只能被某些后代访问而不能访问其他后代,请在需要访问的继承链的第一个类中定义变量:

public abstract class Class<T>
{
}

public class ClassA : Class<ClassA>
{
    static private int number = 7;
}

public class ClassB : Class<ClassB>
{
    static private int number = 7;

    public ClassB()
    {
        ClassA.number = 5;  //Does not compile
        ClassB.number = 6;
    }
}

public class ClassC : Class<ClassC>
{
    static private int number = 7;

    public ClassC()
    {
        Console.WriteLine(ClassA.number);  //Does not compile
        Console.WriteLine(ClassB.number);  //Does not compile
        Console.WriteLine(ClassC.number);  //Compiles
    }
}

您无法在祖先类中定义某些内容并将其从后代中删除。