Nested generic interfaces

2020-06-09 07:48发布

问题:

I have a schema of interfaces like the following (C# .NET4)

interface A 
{

}

interface B 
{
    List<A> a;
}

interface C 
{
    List<B> b;
}

and I implemented it in this way:

public interface A 
{

}

public interface B<T> where T : A 
{
    List<T> a { get; set; }
}

public interface C<T> where T : B
{
    List<T> b { get; set; } // << ERROR: Using the generic type 'B<T>' requires 1 type arguments
}

I don't know how to avoid the error Using the generic type 'B' requires 1 type arguments

回答1:

Since interface B<T> is generic, you need to provide a formal type argument for it when declaring interface C<T>. In other words, the current problem is that you are not telling the compiler what type of interface B interface C "inherits" from.

The two Ts will not necessarily refer to the same type. They can be the same type, as in

public interface C<T> where T : B<T>, A { ... }

or they can be two distinct types:

public interface C<T, U> where T : B<U> where U : A { ... }

The restrictions on the type argument are of course tighter in the first case.



回答2:

C looks like Generic Generic type (for lack of a better word).

Would this definition of C work instead?

public interface C<T,U> where T : B<U> where U : A
{
    List<T> b{ get; set; } 
}


回答3:

since generic type in interface B can only be an instance of type A, in interface C you need to declare T of type B<A>:

public interface A { }
public interface B<T> where T : A
{
    List<T> a { get; set; }
}
public interface C<T> where T : B<A>
{
    List<T> b { get; set; } 
}


回答4:

This is because you have a <List<T>> where T is B<T> at the moment you have it as a List<B> where you need to specify a type for B. This is the reason for your error.

public interface C<T, T2> where T : B<T2>
  where T2 : A
{
  List<T> b { get; set; } 
}

Cast T2 to A and then you will be fine :)



回答5:

you can add one more interface here like

public interface A { }
public interface B<T> where T : A
{
    List<T> a { get; set; }
}
public interface BA : B<A>
{ 
}
public interface C<T> where T : BA
{
    List<T> b { get; set; } // << ERROR: Using the generic type 'B<T>' requires 1 type arguments
}

does it solve the purpose?