2009-06-25 45 views
2

我正在通过一个错误工作。在重新创建以下示例的错误时,我能够确定问题发生的原因。但我坚持要有更好的解决方案。因此,考虑下面的程序:如何在实现接口时从泛型方法中正确地返回T?

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将无法​​正常工作,因为那时酒吧不会implimenting IFoo的

回答

5

嗯,我不是太熟悉这个东西,但它不应该是:

static void CallOutputType<T>(T t) where T : IFoo<T> 
{ 
    t.OutputType(t); 
} 

它工作时,我编译它。

+0

嗯,我想现在来测试这个,有什么我想我可能最终做的是在CallOutputType - ((IFoo )t).OutputType(t);由于其他原因,我无法更改方法常数。 – Bob 2009-06-25 20:42:47

0

如何将这个以酒吧类:

public override Foo OutputType(Foo param) 
    { 
     return this.OutputType((Bar)param); 
    } 
0

如何将你的接口定义,使得param的类型声明,延长IFoo

0

我对此第二个斯宾塞 - 当你的泛型约束是T:Foo时,它将你的Bar变成了Foo,显然你可以调用Foo类的OutputType方法。

0

我不确定你最终想完成的是什么,但这会有帮助吗?

如果您添加一个通用的什么都实现的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); 
    }  
} 
相关问题