如果没有子类中的任何代码,我希望抽象类为每个子类提供不同的静态变量副本。在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类似,但我无法控制子类
答案 0 :(得分:6)
虽然这种方法很好,但我想知道是否有更优雅或内置的方法呢?
没有真正的内置方法可以做到这一点,因为你在这里违反了基本的OO原则。您的基类应该不了解传统面向对象理论中的子类。
话虽如此,如果你必须这样做,你的实现可能与你将要获得的一样好,除非你可以直接向子类添加一些其他信息。如果你需要控制它,并且你不能改变子类,这可能是你最好的方法。
答案 1 :(得分:4)
有一种更优雅的方式。您可以利用通用基类中的静态对于不同类型的每个派生类
的不同这一事实public abstract class BaseClass<T> where T : class
{
public static int x = 6;
public int MyProperty { get { return x; } set { x = value; } }
}
对于每个子类,静态int x对于每个唯一T都是唯一的 让我们派生两个子类,并使用子类的名称作为基类中的泛型T.
public class ChildA: BaseClass<ChildA>
{
}
public class ChildB : BaseClass<ChildB>
{
}
现在,静态MyProperty对于ChildA和ChildB都是唯一的
ChildA TA = new ChildA();
TA.MyProperty = 8;
ChildB TB = new ChildB();
TB.MyProperty = 4;
答案 2 :(得分: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")
{
}
}
答案 3 :(得分: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
抽象并在每个派生类中覆盖它。
答案 4 :(得分: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";
}
}
它对我有用。 接口会更好。
答案 5 :(得分:-1)
简单的解决方案:只需使用“new”一词。
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; }
或者你可以使用私有变量(你不需要使用“new”)和函数来获取和设置:
//in abstract class
private static int Variable;
//get and set methods
//in child class
private static int Variable;
//get and set methods