2


1

総称IListは総称リストから代入可能ではありませんか?
bool IsTypeAGenericList(Type listType)
{
  typeof(IList<>).IsAssignableFrom(listType.GetGenericTypeDefinition())
}

`typeof(List)`が与えられるとfalseを返します。

これは、2つの型パラメータが異なる可能性があるためです。正しいですか。

4 Answer


8


実際には、これは動作します:

public static bool IsGenericList(Type type){if(!type.IsGenericType)はfalseを返します。 var genericArguments = type.GetGenericArguments(); if(genericArguments.Length!= 1)はfalseを返します。

var listType = typeof(IList <>)。MakeGenericType(genericArguments); listType.IsAssignableFrom(type)を返します。 }


3


これは本当に開かれた構築型と関係があります。

あなたが言う時:

class List : IList

あなたは実際に言っています:私のクラスはListと呼ばれ、それはTと呼ばれる1つの型パラメータを持ち、そしてそれは*同じT *を使用してIList <>から構築されるインターフェースを実装します。 そのため、定義部のTと「実装」部のTはどちらも同じ型パラメータを参照しています。コロンの前に宣言してから、コロンの後にすぐに参照します。

`+ IList <> +`のtypeパラメーターもTと呼ばれるため、混乱を招きます - しかし、それは完全に異なる型パラメーターです。 それでは、再宣言しましょう このような具体的なクラス:

class List : IList

これは上記と完全に同等ですが、Listのtypeパラメータを参照するときは "U"、IListからのパラメータを参照するときはTとすることができます。 彼らは異なる種類です。

ジェネリック型定義 + List +(これは + typeof(List <>)+`と言ったときの意味です)がジェネリフ型定義 `+ IList +(これが何であるか)を実装していない理由がわかりやすくなりましたつまり、 + typeof(IList <>)+)と言うときは、オープンな一般的な構築型 + IList +(つまり、List独自の型パラメーターで構築されたIList)を実装します。

そのため、基本的に、ジェネリック型定義は他のジェネリック型定義を継承または実装することはありません。通常、他のジェネリック型定義とともに独自の型パラメータを使用してオープン構築型を実装します。

Ripper234の答えは、Reflectionを使用してこの特定のケースを処理する方法を示しているので、繰り返しはしません。私はこれらのタイプ間の関係を明確にしたかっただけで、少なくともある程度分かりやすいものになったことを願っています。


2


インスタンスは総称型の_never_であるため、メソッドは実際には意味がありません。常に特定の型引数を使用して構成されています。

言い換えれば、代入する "open"変数も代入の値として使用するopenインスタンスへの参照もありません。

あなたが言うように、あなたはタイプパラメータが同じになるかどうかわかりません - だから(例えば)あなたが定義することができます:

クラスBizarreList:IList

関係を表現する方法はいくつかあるはずですが…


1


これがAutoMapperの拡張方法です。

public static bool IsCollectionType(このType型){if(type.IsGenericType)

IEnumerable genericInterfaces = type.GetInterfaces()。ここで、(t => t.IsGenericType); IEnumerable baseDefinitions = genericInterfaces.Select(t => t.GetGenericTypeDefinition());

var isCollectionType = baseDefinitions.Any(t => t == typeof(ICollection <>));

isCollectionTypeを返します。 }