簡體   English   中英

C#反射:如何確定ParameterInfo是否是在父類上定義的泛型類型

[英]C# Reflection: How to determine if ParameterInfo is a generic type defined on parent class

我有這樣的方法簽名:

public class Class1<TItem>
{
    public void CopyTo(TItem[] items) { }
}

在父類上聲明了TItem位置。

當我使用反射來解析此方法時:

// 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文檔中:

<member name="M:ClassLibrary1.Class1`1.CopyTo(`0[])">

我無法可靠地檢測TItem []是否通用,並弄清楚如何(通常)獲取通用索引。

當我查看參數簽名時, ParameterType.IsGenericType.GenericParameterPosition一樣為false。 ParameterType.ContainsGenericParameters為true,但是沒有地方給我通用的原始類型簽名(即,簽名需要的'0[] ,通常在.FullName屬性中看到)。

如果通用定義在實際方法上(即SomeMethod<TItem>(TItem[] blah) ,這一切都可以用,在這一點上我可以根據需要解析參數,但是當通用參數在類型上定義時,我可以不能通過其通用參數位置找出正確的簽名來引用父通用類型。

我認為問題在於您正在查看方法的通用參數,而不是方法的參數。 您還必須區分數組和泛型類型。

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變量的GenericParameterPosition0 檢查DeclaringMethod屬性是否為空值,以確定該位置所指的是:方法或類/接口/結構。

public class Class2<TKey>
{
    public void Foo<TValue>(IDictionary<TKey, TItem> items) { }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM