Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反思:如何推断一种方法';s泛型类型参数?_C#_Reflection - Fatal编程技术网

C# 反思:如何推断一种方法';s泛型类型参数?

C# 反思:如何推断一种方法';s泛型类型参数?,c#,reflection,C#,Reflection,在C#中,您可以使用如下代码通过反射调用通用方法: 公共类示例{ public void Foo(){Console.WriteLine(typeof(T.Name);} } MethodInfo method=typeof(Sample.GetMethod)(nameof(Sample.Foo)); MethodInfo generic=method.MakeGenericMethod(typeof(int)); Invoke(新样本(),新对象[0]); 我想做一些更复杂的事情:泛型参数推

在C#中,您可以使用如下代码通过反射调用通用方法:

公共类示例{
public void Foo(){Console.WriteLine(typeof(T.Name);}
}
MethodInfo method=typeof(Sample.GetMethod)(nameof(Sample.Foo));
MethodInfo generic=method.MakeGenericMethod(typeof(int));
Invoke(新样本(),新对象[0]);
我想做一些更复杂的事情:泛型参数推断,或者类似于重载解析的事情。我需要一个计算泛型类型参数的
Resolve
方法,以便构造实例化的泛型方法:

public static MethodInfo Resolve(MethodInfo genericMI, params Type[] argTypes)
{
    // for example, if genericMI is a reference to 
    // `Sample.Foo2<,>` (below) and argTypes is 
    // `new[] { typeof(List<(int, float)>) }`, this 
    // method would return a `MethodInfo` for 
    // `Sample.Foo2<int, float>`. But how?
}

public class Sample {
    public void Foo1<T>(IEnumerable<T> data) { }
    public void Foo2<T, U>(IEnumerable<(T, U)> data) { }
    public void Foo3<T, U>(IEnumerable<U> list, (T, U) tuple) where U: struct { }
}

// EXAMPLES:
// Returns MethodInfo for Foo1<(int, float)>
var foo2 = Resolve(typeof(Sample).GetMethod("Foo1"), typeof(List<(int, float)>));

// Returns MethodInfo for Foo2<int, float>
var foo2 = Resolve(typeof(Sample).GetMethod("Foo2"), typeof(List<(int, float)>));

// Returns MethodInfo for Foo3<int, byte>
var foo3 = Resolve(typeof(Sample).GetMethod("Foo3"), typeof(List<byte>), typeof((int, byte)));

// Returns null
var failA = Resolve(typeof(Sample).GetMethod("Foo3"), typeof(List<byte>), typeof((int, float)));

// Returns null
var failB = Resolve(typeof(Sample).GetMethod("Foo3"), typeof(List<Regex>), typeof((int, Regex)));

然后,我将通过
delegate.CreateDelegate(…,resolved)
构造一个委托,并使用一些其他技巧缓存该委托,并像普通方法一样调用它以获得良好的性能,因为同一委托通常会被重新用于序列化或反序列化数千个对象。

类型推断算法已描述。理论上,你可以用代码实现它。