当它们都是通用的时,我遇到了实现父/子接口的问题。我能找到的最好的答案是,这是不可能的,但我也找不到其他人提出完全相同的问题。我希望我只是不知道正确的语法,以使编译器理解我正在尝试做的事情。这是我正在尝试实现的代码的精简示例。
public interface I_Group<T>
where T : I_Segment<I_Complex>
{
T Segment { get; set; }
}
public interface I_Segment<T>
where T : I_Complex
{
T Complex { get; set; }
}
public interface I_Complex
{
string SomeString { get; set; }
}
public partial class Group : I_Group<Segment>
{
private Segment segmentField;
public Group() {
this.segmentField = new Segment();
}
public Segment Segment {
get {
return this.segmentField;
}
set {
this.segmentField = value;
}
}
}
public partial class Segment : I_Segment<Complex> {
private Complex complexField;
public Segment() {
this.complexField = new Complex();
}
public Complex Complex {
get {
return this.c_C001Field;
}
set {
this.c_C001Field = value;
}
}
}
public partial class Complex : I_Complex {
private string someStringField;
public string SomeString {
get {
return this.someStringField;
}
set {
this.someStringField = value;
}
}
}
所以在这里,Complex是孙子,它实现了I_Complex而没有错误。 Segment是其父级,它实现I_Segment而不会出错。问题出在祖父母组织,试图实施I_Group。我收到了错误
The type 'Segment' cannot be used as type parameter 'T' in the generic type or method 'I_Group<T>'. There is no implicit reference conversion from 'Segment' to 'I_Segment<I_Complex>'.
我被引导相信这是协方差的问题,但我也被认为这是应该在C#4.0中工作的东西。当孩子不是通用的时,这会起作用,这使我认为必须存在一些语法才能使其正确编译。难道我做错了什么?这甚至可能吗?如果没有,有人可以帮我理解为什么不是吗?
答案 0 :(得分:2)
您可以在I_Group
接口声明中添加第二个泛型类型参数:
public interface I_Group<T, S>
where T : I_Segment<S>
where S : I_Complex
{
T Segment { get; set; }
}
并在Group
类声明中明确指定两种类型:
public partial class Group : I_Group<Segment, Complex>
它将使您的代码编译。
答案 1 :(得分:0)
嗯,要获得使用界面的协方差或逆变,您可以使用“in”和“out”关键字。协方差使用out关键字,例如:
public interface A<out T>
{
T Foo();
}
虽然逆变使用in关键字:
public interface B<in T>
{
Bar( T t );
}
你的问题是你的I_Segment接口不是协变的或逆变的,所以I_Segment与I_Segment不兼容,这就是你得到编译错误的原因。