And*_*dre 5 c# generics c#-4.0
出于某种原因,我正在努力通过使用通用基类从通用接口实现属性,如下所示:
public interface IParent<TChild> where TChild : IChild
{
TChild Child { get; }
}
public interface IChild { }
Run Code Online (Sandbox Code Playgroud)
然后我有一个基类:
public class ParentBase<TChild> : IParent<TChild> where TChild : IChild
{
private TChild _child;
public ParentBase(TChild child)
{
this._child = child;
}
#region IParent<TChild> Members
public TChild Child
{
get { return _child; }
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
现在我有一个新的Parent Derivative和Child对象,如下所示:
public class MyChild : IChild { }
public class MyParent : ParentBase<MyChild>, IParent<IChild>
{
public MyParent(MyChild child)
: base(child)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我想实例化它并获取抽象(接口类型)传递给消费者,如下所示:
IParent<IChild> parent = new MyParent(new MyChild());
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,我无法正确实现TChild,即使我public TChild Child
在ParentBase上定义了属性,编译器也表示它没有实现,即使我明确地尝试实现.正如您所看到的,约束一直到基类.
您正在从ParentBase<MyChild>
和派生 MyParent IParent<IChild>
。没有实施
IParent<IChild> { IChild Child{get; } }
Run Code Online (Sandbox Code Playgroud)
添加显式实现将允许您的原始代码进行编译
public class MyParent : ParentBase<MyChild>, IParent<IChild>
{
public MyParent(MyChild child)
: base(child)
{
}
#region Implementation of IParent<IChild>
IChild IParent<IChild>.Child
{
get { return base.Child; }
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
如果您还像这样进行 IParent 协变:
public interface IParent<out TChild> where TChild : IChild
{
TChild Child { get; }
}
Run Code Online (Sandbox Code Playgroud)
那么你现在可以这样做
IParent<IChild> parent = new MyParent(new MyChild());
Run Code Online (Sandbox Code Playgroud)
或者
ParentBase<MyChild> parent2 = new MyParent(new MyChild());
Run Code Online (Sandbox Code Playgroud)
和
IParent<IChild> parent3 = parent2;
Run Code Online (Sandbox Code Playgroud)
正如 @svick 在答案中指出的那样,通过协方差,您可以通过不派生IParent<IChild>
和删除显式接口实现来简化。