2009-08-21 12 views

Odpowiedz

23

Załóżmy, że masz funkcji, takich jak:

private static string toLower(string s) 
{ 
    return s.ToLower(); 
} 

jest to wersja System.Func że trwa dwa ogólne argumenty, z których pierwszym jest typ pierwszego parametru, drugi jest zwracany typ. Jako takie, można napisać:

Func<string,string> myFunction = toLower; 
string s = myFunction("AsDf"); 
// s is now "asdf" 

we wszystkich wersjach System.Func, ostatni argument jest generyczny typ zwracany, wszyscy inni są rodzaje parametrów, w porządku.

System.Func jest przydatny, ponieważ nie wymaga pisania niestandardowych typów delegatów. Dzięki temu o wiele łatwiej jest współdzielić delegatów z tym samym podpisem.

Say miałem:

public delegate string MyDelegate1(string s); 
public delegate string MyDelegate2(string s); 

MyDelegate1 myDel = new MyDelegate1(toLower); // toLower as above 

Obecnie żaden sposób CONVER mojego delegata MyDelegate1 do obiektu typu MyDelegate2, mimo że mają ten sam podpis metody. Z drugiej strony, jeśli użył Func zamiast deklarowania niestandardowy typ delegata, nie mielibyśmy tego problemu

5

System.Func<T> zwykle stosowane jako argument do innej funkcji. Może to być dowolny delegat, który zwraca wartość T - istnieje wiele wersji do użycia jako delegat z wieloma argumentami.

Jednym z typowych zastosowań jest filtrowanie - na przykład w LINQ można przekazać funkcję, która będzie używana jako filtr w funkcji Enumerable.Where, aby ograniczyć kolekcję. Na przykład:

public bool FilterByName(string value) 
{ 
    return value.StartsWith("R"); 
} 

// .. later 

List<string> strings = new List<string> { "Reed", "Fred", "Sam" }; 

var stringsStartingWithR = strings.Where(FilterByName); 

Jednak w powyższym przypadku, ci, że bardziej prawdopodobne użycie wyrażeń lambda zbudować Func<string,bool> w locie, jak:

var stringsStartingWithR = strings.Where(s => s.StartsWith("R")); 
+0

Technicznie .gdzie() zwraca się do delegata predykatów. Ale ponieważ to tylko specjalny przypadek Func, wszystko w porządku. –

+4

Joel: Nie ma. Enumerable.Where (Of (TSource)) (IEnumerable (Of (TSource)), Func (Of (TSource, Boolean))) Zobacz: http://msdn.microsoft.com/en-us/library/system.linq. enumerable.where.aspx –

+0

W szczególności zdefiniowano go jako Func

2
void Foo() 
{ 
    Func<object, bool> func = Bar; 
    bool b1 = func(new object()); // b1 is true 
    bool b2 = func(null); // b2 is false 
} 

bool Bar(object o) 
{ 
    return o == null; 
} 
0

Użyj go, aby reprezentować dowolny typ delegata, który ma wartość zwracaną.

1

1) Utwórz instancję Func, która ma jeden parametr i jedną wartość zwracaną. 2) Wydanie Func z dwoma parametrami i jednym wynikiem. Odbiera bool i int, zwraca ciąg znaków. 3) Instancja Func, która nie ma parametrów i jednej wartości wyniku. 4) Wywołaj metodę instancji Invoke w anonimowych funkcjach.

przy użyciu System; class Program {static void Main() {

Func<int, string> func1 = (x) => string.Format("string = {0}", x); 
Func<bool, int, string> func2 = (b, x) => 
    string.Format("string = {0} and {1}", b, x); 

Func<double> func3 =() => Math.PI/2; 

Console.WriteLine(func1.Invoke(10)); 
Console.WriteLine(func2.Invoke(true, 20)); 
Console.WriteLine(func3.Invoke()); } }