Byt*_*der 4 c# inheritance static class-members
简洁版本:
我有一个抽象类A。它有一个方法,该方法需要知道特定于每个子类的静态类属性的值。名称和类型相同,只是每个子类的值可以唯一。
我是否可以在基类A中定义此静态属性,以便能够使用A中定义的方法访问它,但保持不同子类的属性值不相关?
还是我将如何实现这样的目标?
长版:
假设我有一个数据模型的抽象基类。它具有公共属性Id(Int32)。
我想在基类中实现一个构造函数,该构造函数根据子类对象的最后分配ID生成一个新ID。
原因是真正的 ID由数据库自动分配,但是每个数据模型对象在构造时都必须具有唯一的ID,而尚未写入数据库。由于数据库仅分配正整数作为ID,因此我的计划是为新创建的数据模型对象分配一个临时的唯一负ID。写入对象后,ID就会更改为真实的ID。
由于我有很多不同的数据模型类都从我的抽象基类派生而来,所以我认为最好在其中包含该功能而不重复它。但是,每个子类都必须有自己的计数器,该计数器指向下一个空闲的负ID,因为不同的类的ID是无关的。
因此,我在每个子类中都需要一个静态属性来存储该类的最后一个分配的临时ID,但是分配它的机制始终相同,并且可以在抽象基类的构造函数中实现。但是,我无法从基类访问必须由子类实现的属性,这意味着我必须在基类中定义它。但是,此静态属性将对所有子类都是全局的吗?这不是我想要的吗?
如何以最优雅的方式实现此临时ID计数器?
简化的代码示例:
public abstract class ModelBase
{
public Int32 Id { get; set; }
protected static Int32 LastTempId { get; set; } = 0;
public ModelBase()
{
Id = --LastTempId;
}
}
public class Model1 : ModelBase
{
public Model1 () : base ()
{
// do something model1-specific
}
}
public class Model2 : ModelBase
{
public Model2() : base()
{
// do something model2-specific
}
}
Run Code Online (Sandbox Code Playgroud)
如果我以这种方式实现它,我担心对于model1和的两个子类model2,继承的静态属性LastTempId都将是同一实例。但是我希望每个子类都有一个单独的计数器,同时仍在基类构造函数中使用它。
子类的static属性不能具有不同的值,因为static属性是该类的属性,而不是其实例的属性,并且不是继承的。
您可以在抽象类上将一个计数器实现为静态属性,并使用抽象类的一个构造函数。
编辑:要为每个子类保存不同的计数器,可以使用将类型(子类)映射到计数器的静态字典。
public abstract class A<T>
{
public static Dictionary<Type, int> TempIDs = new Dictionary<Type, int>();
public int ID { get; set; }
public A()
{
if (!TempIDs.ContainsKey(typeof(T)))
TempIDs.Add(typeof(T), 0);
this.ID = TempIDs[typeof(T)] - 1;
TempIDs[typeof(T)]--;
}
}
public class B : A<B>
{
public string Foo { get; set; }
public B(string foo)
: base()
{
this.Foo = foo;
}
}
public class C : A<C>
{
public string Bar { get; set; }
public C(string bar)
: base()
{
this.Bar = bar;
}
}
B b1 = new B("foo");
B b2 = new B("bar");
C c1 = new C("foo");
C c2 = new C("foo");
Run Code Online (Sandbox Code Playgroud)
b1.ID将会-1,b2.ID将会-2,c1.ID将会-1和c2.ID将会-2