0

リフレクションを使用してコントロールを作成するスクリプトの場合、区別する必要があります

  1. 次のような標準値タイプInt32
  2. 上記のものに基づくジェネリックnull許容型Int32?
  3. のような他の一般的なタイプList<string>

.NET 4.5では、

myType.IsConstructedGenericType

と組み合わせて

myType.IsValueType

取得します

  1. 真偽
  2. True / True
  3. 真/偽

ただし、IsConstructedGenericTypeは、以前の.NETバージョンでは使用できません。.NET 4.0でこれをどのように達成できますか?

4

2 に答える 2

4

あなたはそれを代用することができます.IsGenericType && !.ContainsGenericParameters

キャッチは、ジェネリック型引数のいずれかがそれ自体がオープンジェネリック型であるかどうかを検出しないことです(たとえば、typeof(List<List<>>))。したがって、を使用して再帰的に行う必要がありますGetGenericArguments

このサンプルコードは機能するはずですが、私はそれをテストしておらず、保証もしていません。

public static class TypeExtensions {
    public static bool IsConstructedGenericType(this Type t)
    {
        if (!t.IsGenericType || t.ContainsGenericParameters)
        {
             return false;
        }

        if (!t.GetGenericArguments().All(
             a => !a.IsGenericType || a.IsConstructedGenericType()))
        {
            return false;
        }

        return true;
    }
}

のドキュメントにIsGenericTypeは、この問題に関する非常に役立つ情報が記載されています。

于 2013-01-23T10:04:50.327 に答える
1

IsGenericTypeあなたが与えた例のためにあなたが望むことをします:

using System;
using System.Collections.Generic;
using System.Reflection;

public class Test
{
    static void Main()
    {
        ShowType(typeof(int));
        ShowType(typeof(int?));
        ShowType(typeof(List<string>));
    }

    static void ShowType(Type type)
    {
        Console.WriteLine("{0} / {1}", type.IsGenericType, type.IsValueType);
    }
}

違いは、を使用IsConstructedGenericTypeするとfalseが返されるのtypeof(List<>)に対し、を使用するIsGenericTypeとtrueが返されることです。Type.ContainsGenericParameters.NET 2+でそれらを区別するために使用できます...それでも十分ではありませが、病理学的な場合:

class Foo<T> : Dictionary<T, string> {}

考えてみてくださいtypeof(Foo<>).BaseType

  • IsConstructedGenericType:True(割り当てられたタイプパラメーターが1つ含まれています)
  • IsGenericType:真
  • ContainsGenericParameters:True(まだ割り当てられていない型パラメーターが1つ含まれています)

うまくいけば、これはあなたにとって問題にならないでしょう。

于 2013-01-23T10:06:04.783 に答える