此代碼未編譯:
static class Foo
{
public static Bar Do(Func<Bar> f) => null;
public static Bar<TOut> Do<TOut>(Func<Bar<TOut>> f) => null;
}
public class Bar
{
}
public class Bar<TOut>
{
public static implicit operator Bar<TOut>(TOut i) => null;
}
// Here compiler complains:
// CS0029 Cannot implicitly convert type 'int' to 'Bar'
// CS1662 Cannot convert lambda expression to intended delegate type
// because some of the return types in the block
// are not implicitly convertible to the delegate return type
Foo.Do(() => 1);
我的期望是編譯器會看到 lambda 的回傳型別,并且除非int轉換為Bar<int>. 但是,我看到編譯器決議為第一種方法。
規范的哪一部分定義了這種行為?
uj5u.com熱心網友回復:
這是在Method Invocations 中指定的,當規范討論什么方法宣告可以作為多載決議的候選者時,對于以下形式的呼叫M(A):
構造方法呼叫的候選方法集。對于
F與方法組關聯的每個方法M:
- 如果
F是非通用的,F則在以下情況下是候選物件:
M沒有型別引數串列,并且F適用于A.- 如果
F是泛型且M沒有型別引數串列,F則在以下情況下是候選物件:
- 型別推斷成功,推斷出呼叫的型別引數串列,并且
- [...]
僅從這些規則中,我們可以看到非泛型Do 是候選物件,而泛型Do不是,因為型別推斷失敗。嘗試注釋掉 non-generic Do,您會看到它說“無法推斷型別引數”之類的內容。
uj5u.com熱心網友回復:
我沒有完整的答案,但我有一些觀察:
觀察 1:洗掉非通用版本Do:
static class Foo
{
public static Bar Do(Func<Bar> f) => null;
}
public class Bar
{
public static implicit operator Bar(int i) => null;
}
// CS0411: The type arguments for method 'Foo.Do<TOut>(Func<Bar<TOut>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Foo.Do(() => 1);
,編譯器仍然無法決議Func<Bar<TOut>> f. 因此,它似乎并不認為這個問題是關于選擇了錯誤的過載,而編譯器不能夠匹配() => 1到Func<Bar<TOut>> f隱含在所有。
觀察 2:下面的代碼有效
static class Foo
{
public static Bar Do(Func<Bar> f) => null;
}
public class Bar
{
public static implicit operator Bar(int i) => null;
}
Foo.Do(() => 1);
這表明編譯器正在檢查隱式轉換。
觀察 3:使隱式轉換運算子int作為輸入,盡管使運算子實際上不可用,因為TOut不會被決議,但使編譯器找到運算子:
static class Foo
{
public static Bar<TOut> Do<TOut>(Func<Bar<TOut>> f) => null;
}
public class Bar<TOut>
{
public static implicit operator Bar<TOut>(int i) => null; // Input is `int` now
}
// CS0411: The type arguments for method 'Foo.Do<TOut>(Func<Bar<TOut>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Foo.Do(() => 1);
所以所有這些結合起來讓我認為編譯器只是沒有嘗試哪些泛型型別會導致隱式轉換起作用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/335371.html
