从基类访问子类的静态常量

时间:2017-02-03 22:35:59

标签: c#

我有一个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字段。

有没有办法做到这一点,我忽略了?

6 个答案:

答案 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将返回CatDog.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());