代码之家  ›  专栏  ›  技术社区  ›  ste

使一个超类具有一个静态变量,该变量对于c中的每个子类都是不同的#

  •  7
  • ste  · 技术社区  · 16 年前

    子类中没有任何代码 ,我希望抽象类为每个子类都有一个不同的静态变量副本。在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 ,但我无法控制子类

    5 回复  |  直到 9 年前
        1
  •  12
  •   AustinWBryan ravenspoint    5 年前

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

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

    对于每个子类,静态int x对于每个唯一的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;
    
        2
  •  6
  •   Reed Copsey    16 年前

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

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

        3
  •  2
  •   Pavel Anikhouski    6 年前

    这与您要求的有点不同,但可能实现了相同的目标。

        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")
            {
            }
        }
    
        4
  •  0
  •   Mehrdad Afshari    16 年前

    有一种替代解决方案可能比您的好,也可能不比您的好,具体取决于用例:

    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 在每个派生类中抽象并重写它。

        5
  •  0
  •   Gulyo    13 年前

    这个怎么样?

    
    
        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";
        }
        }
    
    

    界面会更好。

        6
  •  -1
  •   Alexander    5 年前

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

    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;}
    

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

    //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; }
    

    //in abstract class
    private static int Variable;
    //get and set methods
    //in child class
    private static int Variable;
    //get and set methods