我有一个抽象类-let说myBase。我希望从myBase派生的所有类都有一个名为的静态字段
public static List<string> MyPArameterNames
{
get {return _myParameterNames;}
}
因此,每个子类都可以告诉它使用哪些参数名称;我想要静态,因为我不想为此创建一个实例。
我怎样才能做到这一点?
虽然在接口上不可能有static
值,但是可以在抽象类上具有静态值。这个实例虽然保留在抽象类的层次上;因此对所有派生类都是通用的。根据您的需要,您可以利用这一优势;即在您的基类上有一个字典,其键是一个类型(类型是派生类的类型),然后保存您的列表。
//example of the base class
public abstract class MyAbstractBaseClass
{
private static readonly IDictionary<Type,IList<MyAbstractBaseClass>> values = new Dictionary<Type,IList<MyAbstractBaseClass>>();
public List<string> MyParameterNames
{
get
{
return values[this.GetType()].Select(x => x.Name).ToList();
}
}
public string Name {get; private set;}
protected MyAbstractBaseClass(string name)
{
//assign the new item's name to the variable
Name = name;
//keep a list of all derivations of this class
var key = this.GetType();
if (!values.ContainsKey(key))
{
values.Add(key, new List<MyAbstractBaseClass>());
}
values[key].Add(this);
}
}
//examples of dervived class implementations
public class MyDerivedClassOne: MyAbstractBaseClass
{
private MyDerivedClassOne(string name): base(name){}
public static readonly MyDerivedClassOne Example1 = new MyDerivedClassOne("First Example");
public static readonly MyDerivedClassOne Example2 = new MyDerivedClassOne("Second Example");
}
public class MyDerivedClassTwo: MyAbstractBaseClass
{
private MyDerivedClassTwo(string name): base(name){}
public static readonly MyDerivedClassTwo Example1 = new MyDerivedClassTwo("1st Example");
public static readonly MyDerivedClassTwo Example2 = new MyDerivedClassTwo("2nd Example");
}
//working example
void Main()
{
foreach (var s in MyDerivedClassOne.Example1.MyParameterNames)
{
Console.WriteLine($"MyDerivedClassOne.Example1.MyParameterNames: {s}.");
}
foreach (var s in MyDerivedClassTwo.Example1.MyParameterNames)
{
Console.WriteLine($"MyDerivedClassTwo.Example1.MyParameterNames: {s}.");
}
}
它与拥有静态属性并不完全相同(例如,如果不先创建实例就不能简单地访问该属性),但它可能适用于某些用例。
解决方案的所有部分都在这里,分布在多个答案中。
虽然它仍然不允许您从AbstractClass.MyParameterNames访问Subclass.MyParameterNames,但您将能够确保AbastractClass的所有实现都具有该属性。
但是,根据您的用例的具体情况,最好将MyParameterNames公开为非静态成员,并将其简单地实现为单例,以便每个子类只有一个列表副本。无论哪种方式,您仍然需要初始化类的实例以获取所需的数据。
至少,要获取静态数据,您需要知道您正在处理的是哪个特定的子类,因此尝试从接口查看它是没有多大意义的,这可能是任意的,未知数据类型。