12

在子类中没有任何代码,我希望一个抽象类为每个子类拥有一个静态变量的不同副本。在 C# 中

abstract class ClassA
{
    static string theValue;

    // just to demonstrate
    public string GetValue()
    {
        return theValue;
    }
    ...
}
class ClassB : ClassA { }
class ClassC : ClassA { }

和(例如):

(new ClassB()).GetValue(); // returns "Banana"
(new ClassC()).GetValue(); // returns "Coconut"

我目前的解决方案是这样的:

abstract class ClassA
{
    static Dictionary<Type, string> theValue;
    public string GetValue()
    {
        return theValue[this.GetType()];
    }
    ...
}

虽然这很好用,但我想知道是否有更优雅或内置的方式来做到这一点?

这类似于Can I have different copies of a static variable for each different type of inheriting class,但我无法控制子类

4

6 回答 6

12

还有一种更优雅的方式。您可以利用这样一个事实,即通用基类中的静态对于不同类型的每个派生类都是不同的

public abstract class BaseClass<T> where T : class
{
    public static int x = 6;
    public int MyProperty { get => x; set => x = value; }
}

对于每个子类,静态 int x 对于每个唯一的 T 都是唯一的 让我们派生两个子类,我们使用子类的名称作为基类中的泛型 T。

public class ChildA: BaseClass<ChildA>
{
}

public class ChildB : BaseClass<ChildB>
{
}

现在静态 MyProperty 对于 ChildA 和 ChildB 都是唯一的

var TA = new ChildA();
TA.MyProperty = 8;
var TB = new ChildB();
TB.MyProperty = 4;
于 2018-03-30T23:49:28.230 回答
6

虽然这很好用,但我想知道是否有更优雅或内置的方式来做到这一点?

实际上并没有内置的方法来执行此操作,因为您在这里违反了基本的 OO 原则。您的基类不应该了解传统面向对象理论中的子类。

话虽如此,如果您必须这样做,您的实现可能与您将获得的一样好,除非您可以直接向子类添加一些其他信息。如果您需要控制这一点,并且您不能更改子类,这可能是您最好的方法。

于 2009-12-03T21:46:11.310 回答
2

这与您所要求的略有不同,但可能会完成同样的事情。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine((new B()).theValue);
            Console.WriteLine((new C()).theValue);
            Console.ReadKey();
        }
    }

    public abstract class A
    {
        public readonly string theValue;

        protected A(string s)
        {
            theValue = s;
        }
    }

    public class B : A
    {
        public B(): base("Banana")
        {
        }
    }

    public class C : A
    {
        public C(): base("Coconut")
        {
        }
    }
于 2009-12-03T21:59:36.413 回答
0

有一个替代解决方案可能会或可能不会比您的解决方案更好,具体取决于用例:

abstract class ClassA
{
    private static class InternalClass<T> {
        public static string Value;
    }
    public string GetValue()
    {
        return (string)typeof(InternalClass<>)
              .MakeGenericType(GetType())
              .GetField("Value", BindingFlags.Public | BindingFlags.Static)
              .GetValue(null);
    }
}

这种方法用于EqualityComparer<T>.Default. 当然,它不用于这个问题。您应该真正考虑GetValue在每个派生类中制作抽象并覆盖它。

于 2009-12-03T21:48:06.853 回答
0

那这个呢?



    class Base {
    protected static SomeObjectType myVariable;

    protected void doSomething()
    {
    Console.WriteLine( myVariable.SomeProperty );
    }
    }

    class AAA : Base
    {
    static AAA()
    {
    myVariable = new SomeObjectType();
    myVariable.SomeProperty = "A";
    }
    }

    class BBB : Base
    {
    static BBB()
    {
    myVariable = new SomeObjectType();
    myVariable.SomeProperty = "B";
    }
    }

这个对我有用。使用接口会更好。

于 2012-12-12T00:02:51.773 回答
-1

简单的解决方案:只需使用“新”一词。

public abstract class AbstractClass
{
    public static int Variable;
}

public class RealizationA : AbstractClass
{
    public new static int Variable;
}

public class RealizationB : AbstractClass
{
    public new static int Variable;
}

结果:

AbstractClass.Variable = 1;
RealizationA.Variable = 2;
RealizationB.Variable = 3;
Console.WriteLine(AbstractClass.Variable); //1
Console.WriteLine(RealizationA.Variable); //2
Console.WriteLine(RealizationB.Variable); //3

或者您可以使用属性:

//in abstract class
public static int Variable {get; set;}
//in child class
public static new int Variable {get; set;}

或函数(但请记住在变量和函数中添加“新”):

//in abstract class
protected static int Variable;
public static int GetVariable() { return Variable; }
public static void SetVariable(int v) { Variable = v; }
//in child class
protected new static int Variable;
public static new int GetVariable() { return Variable; }
public static new void SetVariable(int v) { Variable = v; }

或者您可以使用私有变量(您不需要使用“new”)和函数来获取和设置:

//in abstract class
private static int Variable;
//get and set methods
//in child class
private static int Variable;
//get and set methods
于 2021-03-19T22:04:50.787 回答