在不更改父类的情况下更改子类中的静态变量
本文关键字:静态 变量 子类 情况下 父类 | 更新日期: 2023-09-27 18:27:46
我希望a.ID()返回0,b.ID()则返回1,这是我的代码:
public class A {
public static int id;
public int ID() {return id;}
}
public class B : A { }
public class Main {
void Program() { //This executes when I execute the program
A.id = 0;
B.id = 1;
}
}
但它不起作用,这也不起作用:
public class A {
public static int id;
public int ID() {return id;}
}
public class B : A {
public new static int id; //id is actually 1 but ID() is still 0
}
public class Main {
void Program() { //This executes when I execute the program
A.id = 0;
B.id = 1;
}
}
我该怎么解决这个问题?
您可以创建两个静态变量和一个虚拟属性
public class A
{
private static int _idA;
public virtual int Id
{
get { return _idA; }
set { _idA = value; }
}
}
public class B : A
{
private static int _idB;
public override int Id
{
get { return _idB; }
set { _idB = value; }
}
}
或者一个属性并使用新的关键字覆盖它
public class A
{
public static int Id { get; set; }
}
public class B : A
{
public static new int Id { get; set; }
}
要测试第一个解决方案,您可以尝试以下
static void Main(string[] args)
{
A test = new B();
new B().Id = 3;
new A().Id = 2;
test.Id = 1;
Console.WriteLine(test.Id + " " + new B().Id + " " + new A().Id);
Console.ReadKey();
}
如果您可以接受这些规则:
- 数字可以是任何数字,即任何合法的
int
- 它们不必从0开始
- 它们不必为每种新的独特类型增加1
- 允许在执行程序之间更改数字
- 即。运行程序后,类型A返回id 33554436
- 您更改程序(在其他地方)并重新运行,现在类型A返回id 33554437(不同的值)
那么这里有一种获取您的身份证的方法:
public class Base
{
public int ID
{
get
{
return GetType().MetadataToken;
}
}
}
你不需要重写这个属性来获得每个类型的唯一id,但你不能再保证值是什么,下面是两个这样的派生类的输出示例:
33554436
33554437
如果我在这两个和reran之间添加一个新类型,我得到:
33554436
33554438
如果你担心持续的反思之旅会很昂贵,这里有一个替代声明:
public class Base
{
private readonly Lazy<int> _ID;
protected Base()
{
_ID = new Lazy<int>(() => GetType().MetadataToken);
}
public int ID
{
get
{
return _ID.Value;
}
}
}
您可以将ID
方法设为虚拟方法,并在B
类中覆盖它,如下所示:
public class A
{
public static int id;
public virtual int ID() { return id; }
}
public class B : A
{
public static int id;
public override int ID()
{
return id;
}
}
这里有另一种使用反射的方法:
public class A
{
public static int id;
public int ID()
{
return (int)this.GetType()
.GetField("id", BindingFlags.Static | BindingFlags.Public)
.GetValue(null);
}
}
public class B : A
{
public static int id;
}
这样,您就不必在每个子类上重写ID
方法。但是,您仍然需要在每个子类中定义一个静态id
字段。