I'm having an issue with implementing parent/child interfaces when both of them are generic. The best answer I've been able to find is that it isn't possible, but I also haven't been able to find anyone else asking the exact same question. I'm hoping that I just don't know the right syntax to make the compiler understand what I'm trying to do. Here is a stripped down example of the code I'm trying to implement.
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;
}
}
}
So here, Complex is the grandchild, which implements I_Complex without error. Segment is its parent, which implements I_Segment without error. The issue is with the grandparent, Group, trying to implement I_Group. I get the error
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>'.
I am led to believe this is an issue with covariance, but I was also led to believe this was something that was supposed to work in C# 4.0. This works when the child isn't generic, which leads me to think that there must exist some syntax to get this to compile properly. Am I doing something wrong? Is this even possible? And if not, could someone help me understand why not?
You can add second generic type parameter into I_Group
interface declaration:
public interface I_Group<T, S>
where T : I_Segment<S>
where S : I_Complex
{
T Segment { get; set; }
}
And specify explicitly both types in Group
class declaration:
public partial class Group : I_Group<Segment, Complex>
It will make your code compile.
Well, to get covariance or contravariance to work with an interface, you use the "in" and "out" keywords. Covariance uses the out keyword, for example:
public interface A<out T>
{
T Foo();
}
While contravariance uses the in keyword:
public interface B<in T>
{
Bar( T t );
}
The problem in your case is that your I_Segment interface is not covariant or contravariant, so I_Segment is not compatible with I_Segment, which is why you get a compile error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.