C# Semi-static semi-abstract 变量

C# Semi-static semi-abstract variable

很难给它起标题,如果你能想到更好的,我会更新它。但我正在寻找的是一种能够从实例 object 引用静态值的方法。例如,假设您有一个名为 Animal 的抽象 class 和两个名为 CatDog 的子 class。在抽象 class 上,我想要一个名为 GenusSpecies 的实例变量,当然,它在 Animal 级别没有值,因为它是一个抽象 class,但每个 Cat 将具有相同的值,但它与所有 Dog 不同。但是,我想让 CatDog classes 对每种类型的实例都有一个静态值,但我不想在每个实例上都设置它的值实例,但我希望能够像实例变量一样引用它,因为我将拥有一个通用变量,例如。

Animal a = new Cat("Garfield");

但我希望

a.GenusSpecies == "Felis catus"

但我不想把 GenusSpecies = "Felis catus"; 在构造函数中。而且,如果能够引用 Cat.GenusSpecies 静态值也很好,因为每个 Cat 类型的实例总是相同的。我知道在某些时候我会区分两种引用方式的区别,但是有什么办法可以同时实现这两种引用类型吗?我希望我已经正确解释了这一点。

public class GenusAttribute : Attribute
{
    public string GenusName {get; private set;}
    public GenusAttribute(string genusName)
    {
        GenusName = genusName;
    }
}

[GenusAttribute("Catus")] // or simply [Genus("Catus")], no need to type 'Attribute' in here
public class Cat : Animal
{

}

我现在在我的 phone 上,所以我不确定这段代码是否有效,但你的基础 class 不能有一个实例 属性 调用静态 属性.

abstract class Base
{
    public abstract static string Value { get; }

    public abstract string InstanceValue { get { return Value; } }
}

我会在可以连接到我的 PC 上测试这是否有效时再回来查看。

您可以将 GenusSpecies 声明为 Animal 中的(只读)字符串字段,并添加一个构造函数,该构造函数会将其值相应地设置为实际实例化的 Type

public abstract class Animal
{
    public readonly string GenusSpecies;
    public string Name { get; set; }

    public Animal(string name)
    {
        Name = name;

        if (this is Dog)
            GenusSpecies = "Canis";
        else if (this is Cat)
            GenusSpecies = "Felis catus";
    }
}

public class Dog: Animal
{
    public Dog(string name): base(name)
    {

    }
}

class Cat : Animal
{
    public Cat(string name): base(name)
    {

    }
}

这样在您的 Main 代码中您将拥有:

class Program
{

    static void Main(string[] args)
    {

        Dog myDog = new Dog("myDog");
        Cat myCat = new Cat("myCat");
        Animal a = new Cat("Garfield");

        Console.WriteLine("Dog {0} has GenusSpecies:{1}", myDog.Name, myDog.GenusSpecies);
        Console.WriteLine("Cat {0} has GenusSpecies:{1}", myCat.Name, myCat.GenusSpecies);
        Console.WriteLine("Animal {0} has GenusSpecies:{1}", a.Name, a.GenusSpecies);

    }
}

通过这里给出的一些建议,我想出了一个解决方案,尽管与我最初希望的有所不同。在创建新的子类时,我一直在寻找开销最少的解决方案,并且还想要一个感觉不像是完全破解或者只是比我正在寻找的代码更冗长的解决方案。所以我找到了一个解决方案,我创建了两个类似于 TheLethalCoder 的解决方案的变量。

public abstract class Animal
{
    public static string GENUSSPECIES;
    public abstract string GenusSpecies { get; }

    public string Name;

    public Animal(string name)
    {
        Name = name;
    }
}

public class Cat : Animal
{
    public static new string GENUSSPECIES = "Felis Catus"; 

    public Cat(string name) : base(name) { }

    public override string GenusSpecies
    {
        get { return Cat.GENUSSPECIES; }
    }
}

起初,我试图从实例变量访问静态值,我认为这应该是可能的,但是,它在这种语言中不可用。所以我做了下一个最好的事情,并将真实值存储为静态值,因为它永远不会改变,但我创建了一个单独的实例 属性,其中 returns 该静态值。添加新子类时很容易维护,只是有点傻,我必须根据我想从中访问值的范围来不同地引用它们。