【发布时间】:2015-03-23 16:48:40
【问题描述】:
我的目标是编写一个包含派生“子实例”的方法的抽象基类。在这种方法中,已经完成了一些计算,这在所有派生类中都很常见。
困难在于基类不能自己创建子类。所以我在我的基类中引入了一个类型参数T 和一个protected abstract 方法,它应该返回一个T 的实例。
public abstract class Base<T> where T : Base<T>
{
public T GetChild()
{
string param = ComplexComputation();
return NewInstanceFrom(param);
}
protected abstract T NewInstanceFrom(string param);
}
// --- somewhere else: ---
public class Derivative : Base<Derivative>
{
public Derivative() { }
protected sealed override Derivative NewInstanceFrom(string param)
{
return new Derivative(param);
}
private Derivative(string param)
{
// some configuration
}
}
这种方法的缺点是我无法确保NewInstanceFrom 仅由基类调用。它也可以被继承自Derivative 的类调用。这就是我想要避免的。
所以我可以将功能封装在私有类或委托中:
public abstract class Base<T> where T : Base<T>
{
public T GetChild()
{
string param = ComplexComputation();
return subElementDerivator(param);
}
protected Base<T>(Func<string, T> subElementDerivator)
{
this.subElementDerivator = subElementDerivator;
}
private Func<string, T> subElementDerivator;
}
// --- somewhere else: ---
public class Derivative : Base<Derivative>
{
public Derivative()
: base(deriveSubElement)
{
}
private Derivative(string param)
: base(deriveSubElement)
{
// some configuration
}
private static Derivative deriveSubElement(string param)
{
return new Derivative(param);
}
}
但这引入了一个新对象。
是否有更简单的方法来阻止Derivative 的继承者访问功能(基类应有权访问)?
【问题讨论】:
-
你的第二个代码示例是我能想到的完成你想要的唯一方法。
-
C#的弱点是创建通用工厂几乎是不可能的。以上可以通过发出我认为的操作码来完成。 -
派生类调用该方法到底有什么问题?是怕自己误调用,还是怕第三方派生类不经过你的同意就调用?
-
@Jon 你带来了很好的理由。我正在开发一个框架,我想清除那些没有实用性或在当前上下文中颠覆概念但可以调用的方法。
-
如果是这种情况,那么设置
internal可见性将解决您的问题。这就是大多数 .NET 框架为其“特殊”构造函数处理相同问题的方式。
标签: c# inheritance