2014-03-26 62 views
6

我一直玩的泛型和代表和我發現了一些我不明白的東西。我有非常相似的一般靜態方法,一個接受Action<T>,第二個接受Func<T>。現在的問題是:如果我打電話給接受Func<T>沒有顯式類型的人,那麼編譯器就可以。但是,接受Action<T>的程序無法編譯(請參閱錯誤消息的代碼)。從動作<T>類型參數不能推斷,但從功能<T>可以

我的問題是:爲什麼編譯器能夠識別返回類型,但無法識別參數類型?

public interface IMessage 
{ } 

public class Message : IMessage 
{ 
} 
static void HandleAction<TMessage>(Action<TMessage> action) 
    where TMessage : IMessage 
{ } 

static void HandleFunction<TMessage>(Func<TMessage> action) 
    where TMessage : IMessage 
{ } 

static void A(Message message) 
{ } 

static Message F() 
{ 
    return new Message(); 
} 

static void Main(string[] args) 
{ 
    // this one is ok 
    HandleFunction(F); 

    // compiler error: 
    // The type arguments for method 
    // 'template_test.Program.HandleAction<TMessage>(System.Action<TMessage>)' 
    // cannot be inferred from the usage. 
    //Try specifying the type arguments explicitly. 
    //HandleAction(A); 

    // this one is ok 
    HandleAction<Message>(A); 
} 

我使用Visual Studio中.NET 4.5 2012

+1

[爲什麼C#編譯器不能從函數簽名中推斷泛型類型委託?](http://stackoverflow.com/questions/19015283/why-cant-c-sharp-compiler-infer-generic- type-delegate-from-function-signature) –

回答

7

方法可以通過它們的參數被重載和所有重載形成一個方法組,因此,例如void Xyz(int i)void Xyz(string s)在同一個方法組中,名爲Xyz。即使用戶只定義了一個方法,編譯器也無法減少參數的類型,因爲編譯器的行爲相當嚴格。

方法不能被返回類型重載,因此不能在同一個類中有int Xyz()string Xyz()。返回類型可以很容易地被編譯器扣除,因爲沒有超載。

這對我來說第一次並不明顯,但是我意識到自己可能會造成過載,這一點已經很明顯了。

+0

所以只有'Function Name'沒有指定參數類型可能是不明確的。 – jayatubi

+0

@jayatubi正確。 –

相關問題