我正在处理一个错误。在重新创建以下示例的错误时,我能够确定问题发生的原因。但我坚持要求更好的解决方案。所以给出以下程序:
public interface IFoo<T> {
T OutputType(T param);
}
class Foo : IFoo<Foo> {
public virtual Foo OutputType(Foo param) {
Console.WriteLine("foo");
return param;
}
}
class Bar : Foo, IFoo<Bar> {
public virtual Bar OutputType(Bar param) {
Console.WriteLine("bar");
return param;
}
}
class Program {
static void Main(string[] args) {
Bar bar = new Bar();
CallOutputType(bar);
bar.OutputType(bar);
}
static void CallOutputType<T>(T t) where T : Foo {
t.OutputType(t);
}
}
我期待输出为:
bar
bar
但我得到的是:
foo
bar
看到像这样简化的问题很明显 Bar.OutputType 没有覆盖 Foo.OutputType 。改善这种设计的最佳选择是什么? Bar.OutputType 无法覆盖 Foo.OutputType ,因为签名不同。更改 Bar.OutputType 的签名以匹配 Foo.OutputType 将不起作用,因为栏不会暗示 IFoo < /强>
答案 0 :(得分:5)
static void CallOutputType<T>(T t) where T : IFoo<T>
{
t.OutputType(t);
}
编译时它起作用了。
答案 1 :(得分:0)
如何将其添加到Bar类:
public override Foo OutputType(Foo param)
{
return this.OutputType((Bar)param);
}
答案 2 :(得分:0)
如何转换您的界面定义,以便param
的类型被声明为扩展IFoo
?
答案 3 :(得分:0)
我是第二个Spencer - 当你的泛型约束是T:Foo时,它将你的Bar强制转换为Foo,显然你可以调用Foo类的OutputType方法。
答案 4 :(得分:0)
我不确定你最终想要完成的是什么,但这会有所帮助吗?
如果您将Generic添加到实现IFoo的内容中,那么您可以在创建派生对象时指定类型...
public class Foo<TFoo> : IFoo<TFoo>
{
}
//Then you code would allow this...
//Again other then returning Bar both times I am not certain exactly what you are
//wanting to accomplish But specifying the type at create will allow you to return Bar
//even if you created a Foo or a Bar...
class Program {
static void Main(string[] args) {
Foo foo = new Foo<Bar>();
CallOutputType(foo);
foo.OutputType(foo);
}
static void CallOutputType<T>(T t) where T : Foo {
t.OutputType(t);
}
}