2015-08-27 7 views
6

In meiner Anwendung, ich habe Code ähnlich folgende:mehrdeutige C# Methodenaufruf mit Delegierten

class Program 
    { 
     static void Main(string[] args) 
     { 
      Method(uri => Task.FromResult(uri)); 
     } 

     static void Method(Func<Uri, Uri> transformer) 
     { 
      throw new NotImplementedException(); 
     } 

     static void Method(Func<Uri, Task<Uri>> transformer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

Wie erwartet, diesen Code ausgeführt ruft die zweite Überlastung der ‚Methode‘, die eine Funktion Delegierten erwarten, dass die Renditen eine Aufgabe. Allerdings, wenn ich den Code ändern mit der anonymen Methode in Main zu vermeiden:

class Program 
    { 
     static void Main(string[] args) 
     { 
      Method(Method2); 
     } 

     static Task<Uri> Method2(Uri uri) 
     { 
      return Task.FromResult(uri); 
     } 

     static void Method(Func<Uri, Uri> transformer) 
     { 
      throw new NotImplementedException(); 
     } 

     static void Method(Func<Uri, Task<Uri>> transformer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

Die C# Compiler beklagt nun, dass mein Aufruf an ‚Methode‘ nicht eindeutig ist. Was vermisse ich?

+1

Sie nicht ein Uri zu Method2 übergeben. –

+0

@SamAxe will er nicht. Er versucht eine * Methodengruppe * ('Methode2') in einen Delegaten umzuwandeln (' Func > ') – dcastro

+0

Möglicherweise weil' TResult' in 'Func ' kovariant ist. – haim770

Antwort

1

Die lange Antwort ist bei https://stackoverflow.com/a/2058854/1223597 (wie Richzilla darauf hingewiesen).

Die kurze Antwort ist, dass der C# -Compiler Team wählte Methode Gruppe Conversions (wie Method(Method2)) ignorieren den Rückgabetyp (hier von Method2) zu machen. Dies gibt ihnen Flexibilität in wie Expression Bäume geparst werden. Leider bedeutet das, dass der Compiler nicht implizit zwischen Ihren 2 Method Signaturen wählen kann.

Wenn Sie eine Lambda-Konvertierung durchführen (Method(uri => Task.FromResult(uri))), muss sich das Compiler-Team nicht um die Analyse der Ausdrucksbaumstruktur kümmern, daher berücksichtigen sie Rückgabetypen.