我试图找出一种方法,可以利用通用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
课程中的static
或base
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)中并接受它作为我想要的至少一个可行的解决方案,还是有另一种方法可以实现这一点?
答案 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);
}
}