2017-06-15 213 views
2

我已經檢查了一些關於反射和重載方法的其他文章,但可以找到任何幫助。我找到的一篇文章是this one,但這並沒有太大的幫助。C#反射,獲取重載方法

我有以下兩種方法:

1 | public void Delete<T>(T obj) where T : class { ... } 
2 | public void Delete<T>(ICollection<T> obj) where T : class { ... } 

我試圖讓法N°1。

我試了一下經典的GetMethod("Delete")的方法,但是因爲有兩個方法用這個名字Ambiguous -Exception被拋出。我嘗試使用其他參數(如GetMethod("Delete", new [] { typeof(Object) }))指定方法模式,但沒有找到任何內容(空返回)。

我想我可能只是循環所有的方法,並檢查參數。

我寫了下面的方法...

public static IEnumerable<MethodInfo> GetMethods(this Type type, String name, Type schemaExclude) 
    { 
     IEnumerable<MethodInfo> m = type.GetRuntimeMethods().Where(x => x.Name.Equals(name)); 
     return (from r in m let p = r.GetParameters() where !p.Any(o => schemaExclude.IsAssignableFrom(o.ParameterType)) select r).ToList(); 
    } 

...返回不包含與schemaExclude類型的參數的方法。

我這樣稱呼它 GetMethods("Delete", typeof(ICollection))沒有按預期工作。

顯然..ICollection'1[T]不可轉讓給ICollection。它也不是IEnumerable,IEnumerable<>ICollection<>。我再一次嘗試了typeof(Object),它確實有效,但是確實返回了這兩種方法(就像它應該的那樣)。

我錯過了什麼?

return type 
    .GetRuntimeMethods() 
    .Where(x => x.Name.Equals("Delete")) 
    .Select(m => new { 
     Method = m 
    , Parameters = m.GetParameters() 
    }) 
    .FirstOrDefault(p => 
     p.Parameters.Length == 1 
    && p.Parameters[0].ParameterType.IsGenericType 
    && p.Parameters[0].ParameterType.GetGenericTypeDefinition() == typeof(ICollection<>) 
    )?.Method; 

符合以下條件的上述器的方法:

+2

構建在使用反射和詢問方法與特定類型的你是不是要求與*兼容*類型的方法,你問帶參數的方法參數那些**特定的**類型。您希望在這方面支持的任何繼承和接口實現都必須由您的代碼處理。所以你要求一個帶有「ICollection」參數的「Delete」方法,而且沒有。 –

+0

@ LasseV.Karlsen感謝您的評論。是的,這就是我所設想的。這就是爲什麼我在我寫的方法中採用了不同的方法,我嘗試檢查應該排除的類型是否由參數類型分配。這應該涵蓋任何類的繼承。你建議檢查什麼?任何建議採取不同的方法? –

+1

你知道編譯時的'T'嗎?然後它就是'GetMethods(「Delete」,typeof(ICollection ))''。否則,您必須使用「Type.MakeGenericType」在前面構建運行時類型。 – HimBromBeere

回答

1

您可以通過檢查其泛型參數類型,這樣查找方法

  • 叫「刪除」,
  • 使用單個參數
  • 使用參數作爲泛型,
  • With th Ë泛型參數類型從ICollection<>

Demo.

+0

謝謝你的回答!這確實解決了我的問題,但我真正需要從演示中唯一需要的是'ParameterType.IsGenericType'部分。我將我的支票更改爲'schemaExclude.IsAssignableFrom(o.ParameterType.IsGenericType?o.ParameterType.GetGenericTypeDefinition():o.ParameterType)'。那就是訣竅 –