Antworten:
Kennen Sie die Delegierten im Allgemeinen? Ich habe eine Seite über Delegierte und Veranstaltungen, die helfen können, wenn nicht, obwohl sie eher darauf ausgerichtet ist, die Unterschiede zwischen den beiden zu erklären.
Func<T, TResult>
ist nur ein generischer Delegat - ermitteln Sie, was dies in einer bestimmten Situation bedeutet, indem Sie die Typparameter ( T
und TResult
) durch die entsprechenden Typpargumente ( int
und string
) in der Deklaration ersetzen . Ich habe es auch umbenannt, um Verwirrung zu vermeiden:
string ExpandedFunc(int x)
Mit anderen Worten, Func<int, string>
ist ein Delegat, der eine Funktion darstellt, die ein int
Argument aufnimmt und a zurückgibt string
.
Func<T, TResult>
wird in LINQ häufig sowohl für Projektionen als auch für Prädikate verwendet (im letzteren Fall TResult
immer bool
). Sie können beispielsweise a verwenden, Func<int, string>
um eine Folge von Ganzzahlen in eine Folge von Zeichenfolgen zu projizieren. Lambda-Ausdrücke werden normalerweise in LINQ verwendet, um die relevanten Delegaten zu erstellen:
Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);
foreach (string s in strings)
{
Console.WriteLine(s);
}
Ergebnis:
Value=3
Value=7
Value=10
A Func<int, string>
isst Ints und gibt Strings zurück. Also, was isst Ints und gibt Strings zurück? Wie wäre es damit ...
public string IntAsString( int i )
{
return i.ToString();
}
Dort habe ich gerade eine Funktion erfunden, die Ints isst und Strings zurückgibt. Wie würde ich es benutzen?
var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;
foreach( int i in lst )
{
str += IntAsString(i);
}
// str will be "12345"
Nicht sehr sexy, ich weiß, aber das ist die einfache Idee, auf der viele Tricks basieren. Verwenden wir stattdessen einen Func.
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
Anstatt IntAsString für jedes Mitglied aufzurufen, habe ich einen Verweis darauf namens fnc erstellt (diese Verweise auf Methoden werden als Delegaten bezeichnet ) und diesen stattdessen verwendet. (Denken Sie daran, dass fnc Ints isst und Strings zurückgibt).
Dieses Beispiel ist nicht sehr sexy, aber eine Menge der cleveren Dinge, die Sie sehen werden, basieren auf der einfachen Idee von Funktionen, Delegaten und Erweiterungsmethoden .
Eine der besten Grundierungen für dieses Zeug, das ich gesehen habe, ist hier . Er hat viel mehr echte Beispiele. :) :)
Es ist ein Delegat, der einen int
als Parameter verwendet und einen Wert vom Typ zurückgibt string
.
Hier ist ein Beispiel für seine Verwendung:
using System;
class Program
{
static void Main()
{
Func<Int32, String> func = bar;
// now I have a delegate which
// I can invoke or pass to other
// methods.
func(1);
}
static String bar(Int32 value)
{
return value.ToString();
}
}
Func<int, string>
Akzeptiert einen int-Wert-Parameter und gibt einen Zeichenfolgenwert zurück. Hier ist ein Beispiel, bei dem eine zusätzliche unterstützende Methode nicht erforderlich ist.
Func<int, string> GetDogMessage = dogAge =>
{
if (dogAge < 3) return "You have a puppy!";
if (dogAge < 7) return "Strong adult dog!";
return "Age is catching up with the dog!";
};
string youngDogMessage = GetDogMessage(2);
HINWEIS: Der letzte Objekttyp in Func (in diesem Beispiel "Zeichenfolge") ist der Rückgabetyp für Funktionen (dh nicht auf Grundelemente, sondern auf ein beliebiges Objekt beschränkt). Daher Func<int, bool, float>
akzeptiert Parameter int und bool Wert und gibt einen Float - Wert.
Func<int, bool, float> WorthlessFunc = (intValue, boolValue) =>
{
if(intValue > 100 && boolValue) return 100;
return 1;
};
float willReturn1 = WorthlessFunc(21, false);
float willReturn100 = WorthlessFunc(1000, true);
HTH