2015-11-19 64 views
5
class Foo<T> 
{ 
    public T Bar() { /* ... */ } 
} 

我想將Bar的名稱傳遞給Type.GetMethod(string)。我可以這樣做,作爲someType.GetMethod(nameof(Foo<int>.Bar)),但這int在這裏是完全任意的;有什麼辦法可以省略它嗎?可悲的是,nameof(Foo<>.Bar)不起作用。在不指定類型參數的情況下在泛型類的成員上使用nameof

在這個玩具案例中,這並不是什麼大不了的事,但是如果有多個類型參數,並且特別是如果它們附有約束條件,拼寫它們全部都可以成爲一項任務。

回答

3

nameof documentation明確說,你想要做是不允許的,不幸的是什麼:

因爲參數必須是語法上的表達,有 是不允許的很多東西都沒有列出有用。下面 是值得一提的是產生錯誤:預定義的類型( 例如,intvoid),空類型(Point?),數組類型 (Customer[,]),指針類型(Buffer*),合格別名(A::B),和 Dictionary<,>,預處理符號(DEBUG), 和標籤(loop:)。

您可以做的最好的方法是在界面中指定Bar,並使用nameof(IFoo.Bar)。當然,如果Bar在其簽名中包含與T相關的內容(如在此特定情況下),則這不是一種選擇。


另一種選擇是創建其中每個T替換object的接口。然後具體類型明確地實現了接口,同時也實現了相同方法的泛型版本。

這有幾個缺點:

  • 較大的API表面
  • 更加困難和容易出錯的重構
  • 失去編譯時類型安全,因爲主叫方可能會使用object接口。

這可能是不合理的,只是使用nameof,但在某些情況下,這種策略是有道理的,其他原因。在這些情況下,能夠使用nameof只是一個便利的獎勵。

+0

「例如,如果Bar在其簽名中包含與T相關的內容」這對我來說就是這種情況(編輯問題以包含此內容)。呃,好吧。 – dlf

+0

對於這種情況,無論如何,我寧願只輸入一些不必要的類型參數。首先,具有'Bar'的'T'和'object'版本會使代碼容易受到與'nameof'相關的重命名錯誤的影響,這些錯誤首先被引入解決。如果我準備好容忍這種情況,那麼只要執行GetMethod(「Bar」)''就會更簡單。生活還要繼續。 :) – dlf

+0

@dlf同意。將我評論的內容轉移到後人的答案中。 – 31eee384

相關問題