我有一个要求,其中每个类都必须具有静态只读属性,以避免魔术字符串。最初,我想到了创建一个基类,以强制每个派生类都实现静态只读属性。由于接口或抽象属性不能用于此目的。有没有办法在C#中实现这一目标? 目前,我的脑海中有以下解决方法,但我很容易看到它会导致将来的混乱,即
public abstract class Base
{
public virtual string StaticProperty { get; }
}
public abstract class Derived : Base
{
public new static string StaticProperty => "Some Value";
}
答案 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)
{
}
}
如您所见,在不调用基本构造函数的情况下,您将得到编译错误:
答案 2 :(得分:1)
您说:
一个具体的例子可能是任何派生类都必须将表名作为静态字符串,以避免魔术字符串。
因此,您想确保这样的属性可能存在,因为您想使用反射来访问它。编写一个单元测试,以反映所有这些类型并使用反射来确保它们包含静态属性。
C#类型系统无法在这里为您提供帮助。编写一个单元测试以声明此结构。