С# - делегат System.Func <>

Как использовать делегат System.Func < > ? Должен ли мы контролировать порядок выполнения funcion или событий, используя его?

простой пример был бы полезен

Ответы

Ответ 1

Предположим, что у вас есть функция, например:

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

Существует версия System.Func, которая принимает два общих аргумента, первый из которых является типом первого параметра, второй - типом возврата. Таким образом, вы можете написать:

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

Во всех версиях System.Func последним общим аргументом является тип возвращаемого значения, все остальные являются типами параметров в порядке.

System.Func полезен, потому что он не требует, чтобы вы писали пользовательские типы делегатов. Это упрощает взаимодействие делегатов с одной и той же сигнатурой.

Скажем, у меня было:

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

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

Теперь нет способа конвертировать мой делегат MyDelegate1 в объект типа MyDelegate2, хотя они имеют одну и ту же подпись метода. С другой стороны, если бы мы использовали Func вместо объявления пользовательского типа делегата, у нас не было бы этой проблемы

Ответ 2

System.Func<T> обычно используется как аргумент другой функции. Это может быть любой делегат, который возвращает значение T - и существует несколько версий для использования в качестве делегата с несколькими аргументами.

Одно из распространенных способов фильтрации - например, в LINQ, вы можете передать функцию для использования в качестве фильтра в функции Enumerable.Where, чтобы ограничить сбор. Например:

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

// .. later

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

var stringsStartingWithR = strings.Where(FilterByName);

Однако в приведенном выше случае вы, скорее всего, будете использовать лямбда-выражения для сборки Func<string,bool> на лету, как:

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

Ответ 3

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;
}

Ответ 4

1) Создайте экземпляр Func с одним параметром и одним возвращаемым значением. 2) экземпляр Func с двумя параметрами и одним результатом. Получает bool и int, возвращает строку. 3) Экземпляр Func, который не имеет параметров и одного результата. 4) Вызовите метод экземпляра Invoke для анонимных функций.

с использованием 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());    } }

Ответ 5

Используйте его для представления любого типа делегата с возвращаемым значением.