定义每个子类定义一次的静态属性的最佳方法是什么?
我编写了以下控制台应用程序来测试静态属性:
using System; namespace StaticPropertyTest { public abstract class BaseClass { public static int MyProperty { get; set; } } public class DerivedAlpha : BaseClass { } public class DerivedBeta : BaseClass { } class Program { static void Main(string[] args) { DerivedBeta.MyProperty = 7; Console.WriteLine(DerivedAlpha.MyProperty); // outputs 7 } } }
正如此控制台应用程序演示的那样, MyProperty
属性对于所有BaseClass实例都存在一次。 是否有使用的模式允许我定义一个静态属性,该属性将为每个子类类型分配存储?
鉴于上面的示例,我希望DerivedAlpha
所有实例共享相同的静态属性,并且DerivedBeta
所有实例共享静态属性的另一个实例。
我为什么要这样做?
我懒洋洋地初始化具有某些属性的类属性名称集合(通过reflection)。 每个派生类实例的属性名称都是相同的,因此将它存储在每个类实例中似乎很浪费。 我不能在基类中使它静态,因为不同的子类将具有不同的属性。
我不想复制在每个派生类中填充集合(通过reflection)的代码。 我知道一种可能的解决方案是定义在基类中填充集合的方法,并从每个派生类中调用它,但这不是最优雅的解决方案。
更新 – 我正在做的事情的例子
在Jon的要求下,这是我正在尝试做的一个例子。 基本上,我可以选择使用[SalesRelationship(SalesRelationshipRule.DoNotInclude)]
属性来装饰我的类中的属性(还有其他属性,这只是一个简化的例子)。
public class BaseEntity { // I want this property to be static but exist once per derived class. public List PropertiesWithDoNotInclude { get; set; } public BaseEntity() { // Code here will populate PropertiesWithDoNotInclude with // all properties in class marked with // SalesRelationshipRule.DoNotInclude. // // I want this code to populate this property to run once per // derived class type, and be stored statically but per class type. } } public class FooEntity : BaseEntity { [SalesRelationship(SalesRelationshipRule.DoNotInclude)] public int? Property_A { get; set; } public int? Property_B { get; set; } [SalesRelationship(SalesRelationshipRule.DoNotInclude)] public int? Property_C { get; set; } } public class BarEntity : BaseEntity { public int? Property_D { get; set; } [SalesRelationship(SalesRelationshipRule.DoNotInclude)] public int? Property_E { get; set; } public int? Property_F { get; set; } }
期望的最终结果
访问FooEntity.PropertiesWithDoNotInclude
将返回List
:
{ "Property_A", "Property_C" }
访问BarEntity.PropertiesWithDoNotInclude
返回List
:
{ "Property_E" }
Jon像往常一样有一个很好的解决方案,虽然我没有看到这里有什么好的属性,因为它们必须明确地添加到每个子类型,并且它们不像属性那样。
Dictionary
方法绝对可行。 这是另一种方法,它明确地声明每个BaseEntity
子类将有一个变量:
class FilteredProperties where T : BaseEntity { static public List Values { get; private set; } // or static public readonly List Values = new List (); static FilteredProperties() { // logic to populate the list goes here } }
这样做的缺点是很难与GetType()
调用配对,例如您可能在BaseEntity
方法中使用。 Dictionary
或其实现懒惰填充的包装器对于该用法更好。
两种可能的方法:
-
使用属性; 用属性装饰每个子类,例如
[MyProperty(5)] public class DerivedAlpha { } [MyProperty(10)] public class DerivedBeta { }
当然,只有当它们是有效常数时才有效。
-
使用字典:
var properties = new Dictionary
{ { typeof(DerivedAlpha), 5) }, { typeof(DerivedBeta), 10) }, };
编辑:既然我们有更多的上下文,Ben的答案是非常好的,使用generics在C#中的工作方式。 它就像字典示例,但内置了懒惰,线程安全和简单的全局访问。
答案一:
使用new int覆盖每个类中的属性
public abstract class BaseClass { public static int MyProperty { get; set; } } public class DerivedAlpha : BaseClass { public static new int MyProperty { get; set; } // !! new int !! } public class DerivedBeta : BaseClass { public static new int MyProperty { get; set; } // !! new int !! } DerivedAlpha.MyProperty = 7; DerivedBeta.MyProperty = 8; BaseClass.MyProperty = 9;
答案二:
将值放在每种类型的字典中
public abstract class BaseClass2 { public static Dictionary propertyStore = new Dictionary(); public static int MyProperty { get { var t = typeof(T); return propertyStore[t]; } set { var t = typeof(T); propertyStore[t] = value; } } } public class DerivedAlpha2 : BaseClass2 { } public class DerivedBeta2 : BaseClass2 { } DerivedBeta2.MyProperty = 7; DerivedAlpha2.MyProperty = 8; // BaseClass2.MyProperty = 9; // does not compile