首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#反射:如何确定ParameterInfo是否是定义在父类上的泛型类型

C#反射:如何确定ParameterInfo是否是定义在父类上的泛型类型
EN

Stack Overflow用户
提问于 2015-12-13 10:17:30
回答 1查看 693关注 0票数 1

我有一个这样的方法签名:

代码语言:javascript
运行
复制
public class Class1<TItem>
{
    public void CopyTo(TItem[] items) { }
}

其中TItem在父类上声明。

当我使用反射来解析这个方法时:

代码语言:javascript
运行
复制
// not returning TItem as generic in signature    
string sig = method.FullName; // ClassLibrary1.Class1`1.CopyTo(TItem[])

if (method.ContainsGenericParameters) // true
{
           Type[] genericArgs = method.GetGenericArguments(); // returns empty
           foreach (Type genericArg in genericArgs)
           {
               loM.cGenericParameters += genericArg.Name + ",";
           }
 }

我需要弄清楚什么是泛型类型签名,以便查看XML文档(需要构建时髦的泛型类型查找签名)。我需要将方法签名映射到XML文档中的内容,如下所示:

代码语言:javascript
运行
复制
<member name="M:ClassLibrary1.Class1`1.CopyTo(`0[])">

我无法可靠地检测TItem[]是否是泛型的,也无法弄清楚如何获得泛型索引(泛型)。

当我查看参数签名时,和.GenericParameterPosition一样,ParameterType.IsGenericType也是假的。ParameterType.ContainsGenericParameters是真的,但是它没有给我提供泛型原始类型签名(即.签名所需且通常在.FullName属性中可见的'0[] )。

如果泛型定义是在实际方法上(即。SomeMethod<TItem>(TItem[] blah),这样我就可以根据需要解析出参数。但是当泛型参数定义在类型上时,我找不到正确的签名来通过泛型参数的位置引用父泛型类型。

EN

回答 1

Stack Overflow用户

发布于 2015-12-13 14:20:06

我认为问题在于你看到的是方法的泛型参数,而不是方法的参数。您还必须区分数组和泛型类型。

代码语言:javascript
运行
复制
if (method.ContainsGenericParameters)
{
    foreach (var parameter in method.GetParameters())
    {
        if (parameter.ParameterType.IsArray)
        {
            var elementType = parameter.ParameterType.GetElementType();

            var genericArgName = elementType.Name;
            var genericParameterPosition = elementType.GenericParameterPosition;
        }
        else if (parameter.ParameterType.IsGenericType)
        {
            foreach (var genericArg in parameter.ParameterType.GetGenericArguments())
            {
                var genericArgName = genericArg.Name;
                var genericParameterPosition = genericArg.GenericParameterPosition;

                // If you need to differentiate between a generic arg that is declared
                // in the method versus being declared in the class/interface/struct:
                if (genericArg.DeclaringMethod == null)
                {
                    // Declared in the class/interface/struct
                }
                else
                {
                    // Declared in the method
                }
            }
        }
    }
}

当你在下面使用像Class2<>.Foo<>这样的东西时,事情会变得有点奇怪--对于foreach循环的两次迭代,genericArg变量的GenericParameterPosition都是0。检查DeclaringMethod属性中是否有空值,以确定该位置所指的是方法还是类/接口/结构。

代码语言:javascript
运行
复制
public class Class2<TKey>
{
    public void Foo<TValue>(IDictionary<TKey, TItem> items) { }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34247315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档