简体   繁体   中英

How to deduce the second generic parameter through the first generic parameter?

I have the following:

interface IGeneric<T> {}

class Test : IGeneric<int> {}

// in an unrelated class
public void foo<T, U>()
    where T : IGeneric<U>
{
    // do something
}

Now I want to call foo as follows: foo<Test>() . But with the code above, it doesn't work, since apparently I need to specify both parameters:

 Using the generic method 'MainClass.foo<T,U>()' requires 2 type arguments

Is there any way to make foo<Test>() work - preferably without having to pass a Test instance? The compiler should be able to deduce U (to int in this case).

No, the language doesn't offer that. What you'd like the language to offer is a construct that lets you get hold of the U from T<U> eg

public void foo<T> : where exists U : T is IGeneric<U>
public void foo<IGeneric<U>>()

But generic syntax is not that sophisticated. The nearest would be one of these:

public void foo<U>( IGeneric<U> t = null)
public void foo<U>( Test t = null)

Which are not what you want?

You can do it in code with an extra interface definition:

internal interface IGeneric { }
interface IGeneric<T> : IGeneric { }


public void foo<T>() where T : IGeneric
{
    var tGenericU= typeof(T)
                .GetInterfaces()
                .Where( i=> 
                           i.IsGenericType 
                        && i.GetGenericTypeDefinition() == typeof(IGeneric<>) )
                .FirstOrDefault();
    Debug.Assert(typeofU != null);
    var typeofU= tGenericU.GetGenericArguments().First();             

    // do something
    Console.WriteLine( typeofU );
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM