我有一个Animal
基类,每个子类都需要一个静态字符串ID用于识别目的。
所以我可能会:
public class Dog : Animal {
public static readonly string ID = "dog";
}
我这样做是因为我经常需要在我的应用中使用Dog.ID
- 在我还没有实例的地方。
但是,当我有一个实例时,我还需要访问它,但我只想在基类中添加GetId()
之类的东西:
public class Animal {
public string GetId() {
return ID;
}
}
问题是,Animal
无权访问子节点中的静态ID字段。
有没有办法做到这一点,我忽略了?
答案 0 :(得分:3)
抽象方法怎么样?
public class Dog : Animal
{
public static readonly string ID = "dog";
public override string GetId()
{
return ID;
}
}
public abstract class Animal
{
public abstract string GetId();
}
或虚拟
public class Animal
{
public virtual string GetId()
{
return null;
}
}
答案 1 :(得分:1)
丑陋......但你可以使用反射:
FieldInfo id = GetType().GetField("ID", BindingFlags.Public | BindingFlags.Static);
return id.GetValue(null);
答案 2 :(得分:1)
如果这是一个静态的set-once 标识符,您似乎应该使用属性而不是static
字段或属性:
public class AnimalIdAttribute : Attribute
{
public AnimalIdAttribute(string id)
{
Id = id;
}
public string Id { get; }
}
public class Animal
{
public string Id => this.GetCustomAttribute<AnimalIdAttribute>(true)?.Id;
}
[AnimalId("dog")]
public class Dog : Animal
{
}
此外,如果任何动物应该提供Id
,那么您的Animal
类应该是abstract
类,它还应该定义一个抽象的Id
属性:
public abstract class Animal
{
// Now you can access Id property implementation
// from Animal
public abstract string Id { get; }
}
public class Dog : Animal
{
public override string Id { get; } = "dog";
}
答案 3 :(得分:0)
或者,您可以这样做:
public class Animal
{
public static string Id;
public virtual string GetId()
{
return Id;
}
}
public class Dog : Animal
{
public new static readonly string Id = "dog";
public override string GetId()
{
return Id;
}
}
这使您能够从Class或实例调用Id。
答案 4 :(得分:0)
如果您同意假设ID
等于类型名称,则可以使用此方法。它允许您在基类中定义和继承ID属性。
虽然我同意这看起来很奇怪。
public class Animal<T> where T : Animal<T>
{
public static readonly string ID = typeof(T).Name;
}
public class Dog : Animal<Dog>
{
}
public class Cat : Animal<Cat>
{
}
表达式Cat.ID
将返回Cat
,Dog.ID
将返回Dog
。
答案 5 :(得分:0)
实现像这样的显式界面
public class Animal : IType
{
private static string _ID = "Animal";
string IType.ID
{
get
{
return getID();
}
}
public virtual string getID()
{
return _ID;
}
}
public class Dog : Animal, IType
{
public static readonly string _dogID = "dog";
string IType.ID
{
get
{
return _dogID;
}
}
public override string getID()
{
return _dogID;
}
}
....
// usage
Animal a = new Animal();
Animal d = new Dog();
Console.WriteLine(a.getID());
Console.WriteLine(d.getID());