4

反射からの型を型パラメーターとして使用できますか?たとえば、渡されたオブジェクトに基づいてパーシスタを選択したい:

IPersister GetPersisterFor(IEntity entity)
{
    return GetPersisterFor<entity.GetType()>(); // <-- this cannot be compiled
}

IPersister GetPersisterFor<TEntity>() where TEntity : IEntity
{
    //some logic to get persister...
}
4

3 に答える 3

4

リフレクション経由のみ。を使用してジェネリック メソッドGetMethodを取得し、それを呼び出す必要があります。MethodInfoMakeGenericMethod(entity.GetType()).Invoke(this, null);

ただし、動的にチートする方が簡単です。

IPersister Evil<T>(T obj) where T : IEntity {
    return GetPersisterFor<T>();
}

そして、最初のメソッドを次のようにします。

return Evil((dynamic)entity);

これは動的表現であり、(Evil-of-T を呼び出すために) 使用する正しい T を検出します。

注: 追加のメソッドが必要な唯一の理由は、名前が同じであるため、再帰的に解決されないようにするためです。

于 2012-12-26T10:29:35.317 に答える
1

はい、ジェネリック メソッド定義を取得する必要があります。その後MethodInfo.MakeGenericMethod、ジェネリック メソッドを構築するために使用できます。

次のようなものです:

MethodInfo genericMethodDefinition = GetType()
    .GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
    .Where(method => method.IsGenericMethod && method.Name == "GetPersisterFor")
    .First();

// OR

MethodInfo genericMethodDefinition = GetType().GetMethod("GetPersisterFor",
    BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

// THEN

MethodInfo genericMethod = genericMethodDefinition.MakeGenericMethod(entity.GetType());
genericMethod.Invoke(this, null);
于 2012-12-26T10:30:56.773 に答える
1

ジェネリック メソッドと非ジェネリック メソッドの名前は同じであるため、クラスのすべてのメソッドを反復処理して適切なメソッドを見つけてから呼び出す必要があります。

public IPersister GetPersisterFor(IEntity entity)
{       
    MethodInfo getPersisterForGenericMethod = 
                    GetType().GetMethods()
                        // iterate over all methods to find proper generic implementation
                        .Single(methodInfo => methodInfo.Name == "GetPersisterFor" && methodInfo.IsGenericMethod)
                        // supply it with generic type parameter
                        .MakeGenericMethod(entity.GetType());

    // invoke it
    return getPersisterForGenericMethod.Invoke(this, null) as IPersister;
}

public IPersister GetPersisterFor<TEntity>() where TEntity : IEntity
{
    return null;
}

ps: gist.githubで入手可能な完全なソース コード

于 2012-12-26T10:52:35.960 に答える