简体   繁体   English

泛型的C#反射

[英]C# Reflection with generics

I have been searching for this for some time but not gotten anywhere. 我已经搜索了一段时间,但没有找到任何地方。 I want to do the following: 我要执行以下操作:

Given a type say Dictionary<string,MyClass> and say its method ContainsKey(string) - at run time I want to be able to extract out the 'Generic signature' of this method. 给定类型说Dictionary<string,MyClass>并说它的方法ContainsKey(string) -在运行时,我希望能够提取出此方法的“通用签名”。 That is I want to get Boolean Dictionary<TKey,TValue>.ContainsKey(TKey) ( and not Boolean ContainsKey(string) ) 那就是我想获取Boolean Dictionary<TKey,TValue>.ContainsKey(TKey) (而不是Boolean ContainsKey(string)

I know that this is possible by doing the following 我知道这可以通过执行以下操作

var untyped_methods = typeof(DictObject).GetGenericTypeDefition().GetMethods();
// and extract the method info corresponding to ContainsKey

However is is possible to get this information directly from the methods reflected from the actual type and not from the Generic types ? 但是,是否可以直接从实际类型而不是通用类型反映的方法中获取此信息? Meaning Can I get the generic definition from methods that have been obtained as follows : 含义我可以从如下获得的方法中获得通用定义:

var actual_typed_methods = typeof(DictObject).GetMethods()

In essence is it possible to get the " un-typed " method signatures from MethodInfo objects returned in the second snippet above directly (not via comparing the lists and figuring out) 从本质上讲,可以直接从上面第二个代码片段中返回的MethodInfo对象获取“ 未类型化 ”的方法签名(而不是通过比较列表并弄清楚)

Thanks 谢谢

EDIT: Maybe this did what you wanted. 编辑:也许这做了你想要的。 Not sure if you were actually looking to Invoke or not. 不知道您是否真的想Invoke

If Invoking, then no (see below). 如果是调用,则否(请参见下文)。 If you just want the definition, then you can use typeof(Dictionary<,>) to get the raw generic definitions. 如果只需要定义,则可以使用typeof(Dictionary<,>)获得原始的泛型定义。


Unfortunately, no if you are wanting to Invoke . 不幸的是,如果您想Invoke ,则不会。

Demonstration of why: 演示原因:

void Main()
{
    var genericDictionaryType = typeof(Dictionary<,>);
    var method = genericDictionaryType.GetMethod("ContainsKey");
    var dict = new Dictionary<string, string>();

    dict.Add("foo", "bar");
    Console.WriteLine("{0}", method.Invoke(dict, new[] { "foo" }));
}

Yields the following error: 产生以下错误:

Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true. 无法对包含ContainsGenericParameters为true的类型或方法执行后期绑定操作。

Sounds simple enough to fix. 听起来很容易修复。 Just call method.MakeGenericMethod(typeof(string)); 只需调用method.MakeGenericMethod(typeof(string)); to get the actual typed MethodInfo object. 获取实际的类型化MethodInfo对象。

Unfortunately again, you cannot. 再一次不幸的是,你不能。

Boolean ContainsKey(TKey) is not a GenericMethodDefinition. 布尔值ContainsKey(TKey)不是GenericMethodDefinition。 MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true. 只能在MethodBase.IsGenericMethodDefinition为true的方法上调用MakeGenericMethod。

Reason for this is because the method defined as bool ContainsKey(TKey) instead of bool ContainsKey<TKey>(TKey) . 原因是因为定义为bool ContainsKey(TKey)而不是bool ContainsKey<TKey>(TKey)

You will need to get the ContainsKey method from the correct Dictionary<TK,TV> signature in order to use it. 您需要从正确的Dictionary<TK,TV>签名中获取ContainsKey方法才能使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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