2017-06-21 2 views
0

In this answer gefolgert wird, habe ich eine LINQ-Erweiterung geschrieben, dass die folgenden delegate verwendet, so kann ich mit einer out Variable in einer Funktion übergeben, wie int.TryParse:Typ kann nicht innerhalb eines generischen Delegaten

public delegate bool TryFunc<TSource, TResult>(TSource source, out TResult result); 

public static IEnumerable<TResult> SelectTry<TSource, TResult>(
    this IEnumerable<TSource> source, TryFunc<TSource, TResult> selector) 
{ 
    foreach (TSource item in source) 
    { 
     TResult result; 
     if (selector(item, out result)) 
     { 
      yield return result; 
     } 
    } 
} 

Um diese Erweiterung verwenden, muss ich ausdrücklich die <string, int> Typen wie so angeben:

"1,2,3,4,s,6".Split(',').SelectTry<string, int>(int.TryParse); // [1,2,3,4,6] 

ich möchte zu entfernen <string, int>, ähnlich wie wir .Select(int.Parse) ohne <int> Angabe nennen kann, aber wenn ich es tue, erhalte ich folgende Fehlermeldung:

The type arguments for method 'LINQExtensions.SelectTry(IEnumerable, LINQExtensions.TryFunc)' cannot be inferred from the usage. Try specifying the type arguments explicitly.


Meine Frage ist, warum kann nicht die Typen abgeleitet werden? Mein Verständnis ist, dass der Compiler die Signaturen von int.TryParse und anschließend die TryFuncdelegate zur Kompilierzeit kennen sollte.

+0

Does https://stackoverflow.com/questions/19015283/why-cant-c-sharp-compiler-infer-generic-type-delegate-from-function-signature Hilfe ? – mjwills

Antwort

2

Es kann nicht abgeleitet werden, weil nur eines dieser Argumente passt und das ist die Zeichenfolge. Der zweite Parameter ist der out int und das kann nicht in den allgemeinen Argumenten angegeben werden, weshalb es sagt, dass die Argumente nicht abgeleitet werden können.

Die einzige Möglichkeit, SelectTry ohne Angabe von Argumenten aufzurufen, besteht darin, dass Sie Ihren Delegaten irgendwo auf int.TryParse verweisen und ihn dann als Parameter übergeben.

Ich weiß, dass dies nicht das ist, was Sie wollen, dies ist die einzige Möglichkeit, die ich kenne, um die Argumente zu spezifizieren.

TryFunc<string, int> foo = int.TryParse; 
var s = "1,2,3,4,s,6".Split(',').SelectTry(foo); 

Denken Sie daran, dass die Parameter 1: 1 entsprechen müssen, um Methoden als Delegaten übergeben zu können. int.TryParse passt TryFunc, aber es stimmt nicht überein SelectTry

Verwandte Themen