How to implement a generic parameter that is not generic

I have an interface with two universal parameters, but it is expected that one of the parameters will be provided by the implementation of the class.

public interface IA<T, U> { ... } public class X<T> : IA<T, int> { ... } public class Y<T> : IA<T, MyClass> { ... } 

However, the other interface has a method that takes an instance of IA as a parameter - however, each instance must be the same (the same class can take a multiplicity of X , but then it will never take the value Y , or vice versa). I tried to present it as a general constrainst, but then I have something like

 public interface IB<T, U, V> where U : IA<T, V> { void MyMethod(U value); } public class Z<T> : IB<T, X<T>, int> { ... } 

Of course, I do not want to write this parameter V , since I cannot choose a value for it. The parameter U already determines what value of V should be! However, I cannot just delete V , because then I could not write a restriction.


Another solution is to not use the restriction:

 public interface IB<T> { void MyMethod(IA<T> value); } 

But in this way I can not guarantee that the IB implementation will receive only one IA implementation (i.e., it will be able to accept both X and Y , and this should not).


Is there a way to avoid creating a generic parameter V in the IB interface (in the first solution), but still mutually excluding IA implementations? Is there any specific reason why the compiler cannot deduce type V and allow me to write only class Z<T> : IB<T, X<T>> , or was this case just not expected in the language specification / was selected, not to be implemented?

+7
generics c #
source share
1 answer

You already have enough generic types to restrict IB<T,U>.MyMethod() from getting both X and Y You just need to define the method argument as accepting a particular type.

  public interface IA<T,U> {} public class X<T> : IA<T,int> {} public class Y<T> : IA<T,string> {} public interface IB<T,U> { void MyMethod(IA<T,U> value); } IB<int,int> foo; X<int> a; Y<int> b; foo.MyMethod(a); // will compile foo.MyMethod(b); // will not compile 

Is there a way to avoid creating a generic parameter V in the IB interface (in the first solution), but still mutually excluding IA implementations? Is there any specific reason why the compiler cannot deduce type V and allow me to write only the class Z: IB> or was this case just not expected in the language specification / was chosen so as not to be implemented?

I don't think how the output works in C #. To infer the type for U , MyMethod will be written as follows.

  public interface IB<T> { void MyMethod<U>(IA<T,U> value); } IB<int> foo = null; X<int> a; foo.MyMethod(a); // int type is inferred by compiler 

You still have to use IA<T,U> in your IB interface. I do not think there is an easy way.

+3
source share

All Articles