确保在派生类中定义静态属性

时间:2018-07-14 09:50:56

标签: c# static

我有一个要求,其中每个类都必须具有静态只读属性,以避免魔术字符串。最初,我想到了创建一个基类,以强制每个派生类都实现静态只读属性。由于接口或抽象属性不能用于此目的。有没有办法在C#中实现这一目标? 目前,我的脑海中有以下解决方法,但我很容易看到它会导致将来的混乱,即

基类

public abstract class Base
{
    public virtual string StaticProperty { get; }
}

派生类

public abstract class Derived : Base
{
    public new static string StaticProperty => "Some Value";
}

3 个答案:

答案 0 :(得分:1)

您的问题是没有强制您实现它的约束,因此无论如何在基类中定义它似乎都是多余的。

不幸的是,替代方案同样存在问题,并且存在相同的问题,即您必须为每个派生类创建一个新分支。

array
  .group_by { |h| h["team"] }
  .map do |_, a|
    ["point", "score"].each { |k| a.first[k] = a.sum { |h| h[k] } }
    a.first.merge({"qualified": a.first["score"] > 5 ? 'yes' : 'no'})
  end

用法

public abstract class Derived : Base
{

}
public static class Helper<T> where T : Base
{
   public static string SomeProperty => GetMyProperty();

   public static string GetMyProperty()
   {
      if (typeof(T) == typeof(Derived))
      {
         return "asd";
      }

      throw new ArgumentOutOfRangeException();
   }
}

另一种选择可能是使用属性,但是这取决于您要如何获取这些值,无论如何您仍然需要一个助手或静态属性来获取它们

var test = Helper<Derived>.SomeProperty;

// or

var test = Helper<Derived>.GetMyProperty();

答案 1 :(得分:1)

我不确定我是否理解您的问题,但是我认为解决方案非常简单。您真的需要静态属性吗?如果没有,只需添加一个带有参数的私有构造函数即可初始化属性:

public abstract class Base
{
    public string StaticProperty { get; }

    protected Base(string staticProperty)
    {
        StaticProperty = staticProperty ?? throw new ArgumentNullException(nameof(staticProperty));
    }
}

然后,在派生类中,调用基本构造函数(否则会出现编译错误):

public class Derived : Base
{
    public Derived(string staticProperty) : base(staticProperty)
    {
    }
}

如您所见,在不调用基本构造函数的情况下,您将得到编译错误:

enter image description here

答案 2 :(得分:1)

您说:

  

一个具体的例子可能是任何派生类都必须将表名作为静态字符串,以避免魔术字符串。

因此,您想确保这样的属性可能存在,因为您想使用反射来访问它。编写一个单元测试,以反映所有这些类型并使用反射来确保它们包含静态属性。

C#类型系统无法在这里为您提供帮助。编写一个单元测试以声明此结构。