3

ジェネリック クラス内にジェネリック メソッドがあります。このメソッド内で、メソッドのジェネリック パラメーターの型がマップされていない場合、親の型に対して同じメソッドを呼び出す必要がありますが、親はマップされます。2 ビットのコードで異なる結果が得られますが、同じであると期待しています。

これは成功します:

MethodInfo methodInfo2 = this.GetType().GetMethods()[9]; // this is the correct one.
methodInfo2 = methodInfo2.MakeGenericMethod(mappedType);

これはクラッシュします:

MethodInfo methodInfo1 = System.Reflection.MethodBase.GetCurrentMethod() as MethodInfo;
methodInfo1 = methodInfo1.MakeGenericMethod(mappedType);

この例外を除いて:

GenericArguments[0], 'GenericClassConstraintAbstract.Abstract', on 'System.Collections.Generic.IList`1[Entity] GetEntities[Entity](System.Linq.Expressions.Expression`1[System.Func`2[Entity,System.Boolean]], Sbu.Sbro.Common.Core.Pagination.Paginator`1[Entity])' violates the constraint of type 'Entity'.

methodInfo1 == methodInfo2デバッガ ウォッチを追加すると、 が表示されますfalseが、違いがわかりません。を使用して適切な方法を選択し、そのようにするよりも賢くすることができますが[9]、クラッシュするバージョンがそうする理由も知りたいです。

何か案は?

編集:より良い例で:

interface BaseInterface
{ }

interface MyInterface : BaseInterface
{ }

abstract class Abstract : MyInterface
{ }

class Concrete : Abstract, MyInterface
{ }

class ProblemClass<GenericType> where GenericType : BaseInterface
{
    public virtual IList<Entity> ProblemMethod<Entity>() where Entity : class, GenericType
    {
        if (typeof(Entity) == typeof(Concrete))
        {
            MethodInfo methodInfo = System.Reflection.MethodBase.GetCurrentMethod() as MethodInfo;
            var t1 = this.GetType();           // perhaps the problem resides in
            var t2 = methodInfo.DeclaringType; // these two not being equal?
            methodInfo = methodInfo.MakeGenericMethod(typeof(Abstract));
            return (methodInfo.Invoke(this, new Object[] { }) as IList).OfType<Entity>().ToList();
        }
        else
        {
            return new List<Entity>();
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        new ProblemClass<MyInterface>().ProblemMethod<Concrete>();
    }
}
4

1 に答える 1

3

したがって、問題は、宣言型がオープン ジェネリックであり、ジェネリック メソッドの制約が型のジェネリック型パラメーターに依存していたことです。

次のコードは問題を解決しました:

MethodInfo methodInfo = System.Reflection.MethodBase.GetCurrentMethod() as MethodInfo;
methodInfo = this.GetType().GetMethod(methodInfo.Name, methodInfo.GetParameters().Select(p => p.ParameterType).ToArray());
methodInfo = methodInfo.MakeGenericMethod(typeof(Abstract));
return (methodInfo.Invoke(this, new Object[] { }) as IList).OfType<Entity>().ToList();

http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod.aspxのコメントを参照してください。

于 2013-04-30T15:52:44.083 に答える