2016-11-22 116 views
1

泛型方法与表达我有应该从表中返回的最后一条记录的一般方法:呼叫通过反射

public T FindLast<TKey>(Expression<Func<T,TKey>> specification = null) 
{ 
    return specification == null 
     ? Set().LastOrDefault() 
     : Set().OrderBy(specification).LastOrDefault(); 
} 

我需要通过反射

var methodCreateReadRepositoryAttr = (entityMetadata.GetEntityAttributeType() != null) ? 
typeof(IRepositoryFactory).GetMethod("CreateReadRepository").MakeGenericMethod(entityMetadata.GetEntityAttributeType()) : null; 

var methodEntityGet3 = attributeReadRepository.GetType().GetMethod("FindLast", new Type[] { typeof(Expression<Func<ArticleAttribute,int>>) }); 

但在调试methodEntityGet3叫它一片空白。我做错了什么?

+0

你可以调用它没有反映? –

回答

0

您需要打破你的方法调用两个:

var methodEntityGet3 = attributeReadRepository.GetType().GetMethod("FindLast"); 
var closedGenericMethod = methodEntity3.MakeGenericMethod(new Type[] { typeof(Expression<Func<ArticleAttribute,int>>) }; 
1

问题是您正在请求一种封闭类型的方法,同时方法FindLast是通用类型,并且具有开放类型,即参数类型为Expression<Func<T, TKey>>,而不是您提供的类型。反思系统不会去创建最适合的通用方法,因为这可能取决于语言中的规则。您可能会将参数转换为dynamic,但我不完全确定这一点。

此外,有没有简单的方法来获取类型参数TTKey,所以我建议你搜索方法只能用它的名字,然后明确创建下面的泛型方法,像你这样的方法同上。

编辑:实际上,dynamic解决方案实际上工作,并且可能比任何反射调用可读性要好得多。下面的代码编译和输出可以预期的:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var foo = new Foo<string>(); 
     Expression<Func<string, int>> arg = s => s.Length; 
     CallFindLast(foo, arg); 
     Console.Read(); 
    } 

    private static void CallFindLast(Foo<string> foo, object arg) 
    { 
     var dynamicArg = (dynamic)arg; 
     foo.FindLast(dynamicArg); 
    } 

    private class Foo<T> 
    { 
     public T FindLast<TKey>(Expression<Func<T, TKey>> specification = null) 
     { 
      Console.WriteLine($"T: {typeof(T).Name}, TKey: {typeof(TKey).Name}"); 
      return default(T); 
     } 
    } 
}