定义每个子类定义一次的静态属性的最佳方法是什么?

我编写了以下控制台应用程序来测试静态属性:

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