[英]Why is C# unable to infer the generic type argument type form a non-generic static method's signature?
我進行了以下推理測試:
static class InferenceTest {
static void TakeInt(int a) { }
static int GiveInt() { return 0; }
static int TakeAndGiveInt(int a) { return 0; }
static void ConsumeAction1<T>(Action<T> a) { }
static void ConsumeFunc1<T>(Func<T> f) { }
static void ConsumeFunc2a<T1, T2>(Func<T1, T2> f) { }
static void ConsumeFunc2b<T>(Func<int, T> f) { }
static void ConsumeFunc2c<T>(Func<T, T> f) { }
static void ConsumeFunc1Func2<T1, T2>(Func<T1> f1, Func<T1, T2> f2) { }
static void Main() {
ConsumeAction1(TakeInt); //error
ConsumeFunc1(GiveInt); //ok
ConsumeFunc2a(TakeAndGiveInt); //error
ConsumeFunc2b(TakeAndGiveInt); //ok
ConsumeFunc2c(TakeAndGiveInt); //error
ConsumeFunc1Func2(GiveInt, TakeAndGiveInt); //ok
}
}
結果似乎表明C#編譯器無法從非泛型方法組推斷委托函數參數的泛型類型參數。
最讓我困惑的是,C#可以從ConsumeFunc1Func2
的方法返回值推斷Func<T1, T2>
的類型參數,但無法推斷ConsumeFunc1Func2
中Func<T, T>
的ConsumeFunc2c
。
這個問題類似於F的函數<S,T>只有當S和T不同時才從lambda表達式的輸出中推斷出來? 問題,但我們有非通用的方法組,而不是具有未知參數類型的lambda。
為什么不能從這個看似簡單,明顯的案例問題推斷C#類型的問題,回答問題“為什么非模糊的非泛型方法不足以推理?” 和“為什么參數類型和推理的返回值類型之間存在差異?”。
問題:
為什么C#編譯器可以使用返回值的類型推斷出Func<T>
的類型,但是在Func<T, T>
情況下無法看到成功?
C#編譯器為什么可以推斷出T1
為類型參數Func<T1, T2>
從Func<T1>
在ConsumeFunc1Func2
,但不能推斷T
為類型參數Func<T, T>
從本身在ConsumeFunc2c
這似乎是更容易?
不檢查方法參數。
如建議的那樣,在ConsumeFunc1Func2中,編譯器僅從返回值推斷。 在ConsumeFunc2c中,未檢查TakeAndGiveInt簽名以查看其方法參數類型是否實際上與方法返回類型相同的類型原因...未檢查方法參數!
通常,方法名稱不會唯一標識可以為其分配方法組的唯一類型Action<T>
。 例如,即使只有一個Fred
重載並且只需要一個Cat
參數,該重載不僅可以分配給Action<Cat>
,還可以分配給其他類型,如Action<Mammal>
, Action<Animal>
,或Action<Object>
。 雖然在某些情況下,一種類型的替代在各方面都優於任何替代方案,但情況並非總是如此。 定義語言要求指定委托類型比讓編譯器試圖“猜測”更清晰,特別是因為編譯器猜測會意味着許多不應該破壞變化的東西(例如添加方法重載可能會導致模糊的類型推斷(以前的工作)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.