如何通过第一泛型参数推导第二泛型参数?

时间:2019-12-21 17:23:19

标签: c# generics

我有以下内容:

interface IGeneric<T> {}

class Test : IGeneric<int> {}

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

现在,我要按以下方式致电foofoo<Test>()。但是使用上面的代码,它不起作用,因为显然我需要指定两个参数:

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

有什么方法可以使foo<Test>()正常工作-最好不必传递Test实例吗?编译器应该能够推断出U(在这种情况下为int)。

1 个答案:

答案 0 :(得分:2)

不,该语言不提供。您想要提供的语言是一种结构,可让您从U中获取T<U>,例如

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

但是通用语法并不那么复杂。最接近的将是以下之一:

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

您不想要什么?

可以使用带有额外接口定义的代码来做到这一点:

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 );
}