1
我试图Reflection.Emit
泛型类实现了使用该类的泛型参数构造的泛型接口,例如,这样的:Reflection.Emit:获取具有GenericTypeParameterBuilder类型参数的构造类型的MethodInfo
class Foo<U>: IEquatable<U>
{
bool IEquatable<U>.Equals(U other) { /* ... */ }
}
我挣扎得到MethodInfo
为IEquatable<U>.Equals(U)
方法。
反射构造类型IEquatable<U>
抛出一个NotSupportedException
因为U
是GenericTypeParameterBuilder
,而TypeBuilder.GetMethod(IEquatable<U>, IEquatable<T>.Equals(T))
返回一个怪异IEquatable<U>.Equals(T)
方法。
任何帮助表示赞赏!
测试代码:
// define class Foo<U>
var tb = moduleBuilder.DefineType("Foo");
var genParams = tb.DefineGenericParameters("U");
// IEquatable<T>.Equals(T) method
var miEqualsT = typeof(IEquatable<>).GetMethod("Equals", typeof(IEquatable<>).GetGenericArguments());
// IEquatable<U> constructed type
var iEquatableU = typeof(IEquatable<>).MakeGenericType(genParams);
// now trying to get IEquatable<U>.Equals(U) method
MethodInfo miEqualsU;
try { miEqualsU = iEquatableU.GetMethod("Equals", genParams); }
catch (NotSupportedException) { Console.WriteLine("Reflecting constructed interface not supported."); }
miEqualsU = TypeBuilder.GetMethod(iEquatableU, miEqualsT);
var declaringType =$"{miEqualsU.DeclaringType.Name}<{miEqualsU.DeclaringType.GenericTypeArguments[0].Name}>";
var parameterType = miEqualsU.GetParameters()[0].ParameterType;
Console.WriteLine($"TypeBuilder.GetMethod() returns {declaringType}.{miEqualsU.Name}({parameterType.Name})");
// OUTPUT:
// Reflecting constructed interface not supported.
// TypeBuilder.GetMethod() returns IEquatable`1<U>.Equals(T)
是的,我认为OP是在解决问题,并试图让他所有的鸭子连续,并认为他需要'MethodInfo'用于'IEquatable .Equals(U o)' - 其中方法信息被认证。在实践中,这样的方法信息对象是不必要的,因为你所需要做的就是用正确的_signature_定义一个方法(就像你所做的那样),然后你就可以很好地去做。 –
谢谢你的回答!我注意到它的确如此,但不相信它是正确的。原来我们发出的东西等同于'Foo :IEquatable {bool IEquatable .Equals(U other){/*...*/}}',这似乎很奇怪。但是我发现它('TypeBuilder.CreateType()'?)可以变得有意义,因为我们永远不可能拥有'class Foo :IEquatable ,IEquatable '。仍然感到惊讶的是,我们必须“实现”一个泛型类型定义。 –
tinudu
@tinudu再看一次,我很好奇我写的原始代码甚至是如何工作的。在我看来代码应该是:'tb.AddInterfaceImplementation(typeof(IEquatable <>)。MakeGenericType(genParams))''。经过一些测试(使'Foo '和添加实现'IEquatable <>')产生'Foo :IEquatable ',所以我不太确定在分配泛型参数方面幕后发生了什么。我们需要明确地添加* any *方法的实现(不仅仅是泛型) - 我们只是被C#自动提供了一个基于匹配签名的实现 – Rob