2

複数の型制約を持つジェネリック メソッドがあるとします。これは次のとおりです。

public static void DoSomethingAwesome<T>(T thing)
    where T : IThing, IAwesome, IComparable<T>
{
    ...
}

さて....リフレクションを使用して、そこに送信できるものを作成するにはどうすればよいですか?

それがたった1つの制約である場合、私は次のようにできることを知っています:

var types = assembly
      .GetTypes()
      .Where(typeof (IThing).IsAssignableFrom)

foreach(var t in types)
    DoSomethingAwesome((IThing) Activator.CreateInstance(t));

しかし、実際には複数のインターフェイスにキャストすることはできません...どうすればこれを解決できますか? あなたは私が今ここでかなり迷っていると言うことができます:P

タイトルが長く複雑になってしまいました。これを何と呼べばいいのかわからなかったので、できれば改善してください

4

3 に答える 3

4

適切な型の検索に関するReedとLorenの回答に追加するには、キャストによってDoSomethingAwesomeを呼び出すことはできません。これは、コンパイラがインスタンス化されたオブジェクトを複数のインターフェイスにキャストする方法を提供していないためです。2つのオプションがあります。

  1. IThing、IAwesome、およびIComparable <T>から派生した新しいインターフェイスIAwesomeComparableThingを作成し、タイプにそれを実装させ、それにキャストします。

  2. リフレクションを通じてDoSomethingAwesomeを呼び出します。これを行うには、DoSomethingAwesomeジェネリックメソッドのMethodInfoを取得してから、3つのインターフェイスすべてを実装するタイプでMethodInfo.MakeGenericMethodを呼び出す必要があります。

(2)の例:

Type type = sometype; // For example found using reeds method
MethodInfo mgeneric = typeof(Awesomeiser).GetMethod("DoSomethingAwesome");
MethodInfo mspecific = mgeneric.MakeGenericMethod(new [] { type });
mspecific.Invoke(null, new [] { type });
于 2009-10-05T19:15:23.357 に答える
0

できない理由があるんだと思う

var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom))
于 2009-10-05T18:56:36.967 に答える
0

すべての制約から割り当て可能な型が必要です。最初の 2 つは簡単ですが、3 番目は少しトリッキーです。

// Using
static bool IsIComparable(Type thing)
    {
        foreach (Type interfaceType in thing.GetInterfaces())
        {
            if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IComparable<>))
            {
                Type[] arguments = interfaceType.GetGenericArguments();
                if (arguments.Length == 1)
                {
                    if (arguments[0] == thing)
                        return true;
                }
            }
        }
        return false;
    }


// This returns an enumerable of compatible types:
var types = assembly.GetTypes().Where( t => 
   typeof(IThing).IsAssignableFrom(t) &&
   typeof(IAwesome).IsAssignableFrom(t) &&
   IsIComparable(t) );
于 2009-10-05T19:03:55.970 に答える