我正在尝试为抽象通用基类提供接口。我希望在接口上公开一个使用泛型类型的方法,但其实现最终由从我的抽象泛型库继承的类处理。
但是我不希望子类必须向下转换才能使用泛型类型(因为他们已经知道类型应该是什么)。
这是我现在可以看到的唯一方式的简单版本。
public interface IFoo
{
void Process(Bar_base bar);
}
public abstract class FooBase<T> : IFoo
where T : Bar_base
{
abstract void Process(T bar);
// Explicit IFoo Implementation
void IFoo.Process(Bar_base bar)
{
if (bar == null) throw new ArgumentNullException();
// Downcast here in base class (less for subclasses to worry about)
T downcasted_bar = bar as T;
if (downcasted_bar == null)
{
throw new InvalidOperationException(
string.Format("Expected type '{0}', not type '{1}'",
T.ToString(), bar.GetType().ToString());
}
//Process downcasted object.
Process(downcasted_bar);
}
}
然后FooBase的子类看起来像这样......
public class Foo_impl1 : FooBase<Bar_impl1>
{
void override Process(Bar_impl1 bar)
{
//No need to downcast here!
}
}
显然这不会为我提供编译时类型检查,但我认为它可以完成工作......
问题:
1.我认为这会起作用吗?
这是最好的方法吗?
3.这样做有什么问题?
你能提出一个不同的方法吗?
谢谢!
编辑:在回答许多答案时,要求IFoo不是Generic。我需要能够操纵一组IFoo对象,而不管它们使用的泛型类型。
编辑:努力澄清这个原因...
Bar_base包含对IFoo类型的引用。并且必须调用process方法来验证它包含的数据。可以将IFoo视为包含Bar_base派生对象的验证逻辑的对象。当对Bar_base对象的有效性提出质疑时,它会在其IFoo引用上调用Process来验证自身。
IFoo不能通用的原因是我需要能够引用独立于Bar_base类的IFoo集合。
我将尝试使用两个接口的方法,一个包含Process方法的Generic,另一个不包含非泛型的接口。
答案 0 :(得分:1)
在IFoo不能通用的情况下,在这种情况下,通常有两个接口IFoo<T>
和IFoo,其中IFoo使用支持的最大基类。想想IEnumerable<T>
和IEnumerable。非泛型版本通常作为接口重载隐藏,因此只有在通过非泛型接口访问类时才会发挥作用。
答案 1 :(得分:1)
鉴于你的约束条件是T类型为Bar_base,并且(在你的例子中)只使用T代表进程(T bar),我不确定你为什么要使用泛型。如果
abstract Process(Bar_base bar)
就是你所需要的,然后这应该足以用
覆盖类void override Process(Bar_impl1 bar)
和你的抽象类Bar_base是一个足够的类型约束。
除非我错过了什么......
另一个有用的技巧是提供通用和非通用接口定义,其中非泛型提供非泛型访问方法和属性,而泛型接口仅提供需要泛型类型的其他方法和/或属性。客户端可以指定任一接口,具体取决于它们是否能够共享泛型类型。
interface IFoo
{
...
}
interface IFoo<T> : IFoo where T : Bar_base
{
...
}
但在这种情况下,我不确定这是否能满足您的需求。
答案 2 :(得分:0)
你可以让IFoo通用:
public interface IFoo<T> where T : Bar_base
{
void Process(T bar);
}
答案 3 :(得分:0)
您不仅仅使用通用接口的原因: -
public interface IFoo<T>
where T:Bar_base
{
void Process(T bar);
}