接口和泛型的两种方式引用
我有一个带有泛型的类,它使用另一个类,而该类又需要知道初始类的哪个实例“拥有”它 - 这会导致问题;)让我举一个例子:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
这不起作用,因为 Foo = this不起作用 - 即使我尝试将其转换为 IFoo (编译但在运行时失败)。我尝试以各种方式调整代码,但我还没有找到有效的实现...
希望您看到我正在尝试做的事情,也许您甚至看到我如何实现这一点;-)
I've got a class with generics which uses another class, which in return needs to know what instance of the initial class "owns" it - which causes problems ;) Let me give an example:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
This doesn't work as Foo = this doesn't work - even if I try to cast this to IFoo (compiles but fails at run time). I've tried to tweak the code various ways, but I've not found an implementation that works...
Hopefully you see what I'm trying to do, and perhaps you even see how I can achieve this ;-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以通过组合构造函数中的显式强制转换以及 c#4.0 对泛型参数协方差的支持来解决此问题。
首先,您需要在
Foo
构造函数中插入强制转换:但仅仅这样做还不够。您对
T : new()
的约束意味着T
需要是一个具体的类。因此,IFoo
永远不会完全是IFoo
。但是,如果您指定IBar
的通用参数T
是协变的,则从IFoo
到的转换>IFoo
将变得合法:out
关键字指定该参数是协变的(本质上意味着“该参数只会通过方法输出,从不输入。”)这篇 MSDN 文章 提供了有关协变和逆变的更多详细信息。
You can solve this with a combination of an explicit cast in the constructor, along with c#4.0 support for covariance on generic parameters.
First, you need to insert a cast in the
Foo<T>
constructor:Just doing that isn't sufficient, though. Your constraint that
T : new()
means thatT
needs to be a concrete class. As such,IFoo<T>
will never be exactlyIFoo<IBar>
. However, if you specify that the generic parameterT
forIBar<T>
is covariant, then the cast fromIFoo<Bar>
toIFoo<IBar>
will become legal:The
out
keyword specifies that the parameter is covariant (which essentially means "this parameter will only be output by methods, never input.")This MSDN article offers more details on covariance and contravariance.
将
IFoo
的T
类型参数声明为协变可以解决您的问题吗?这段代码应该允许你做你正在尝试的事情:
Would declaring the
T
type parameter ofIFoo
as covariant solve your problem?This code should allow you to do what you are trying: