С# - делегат 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
Используйте его для представления любого типа делегата с возвращаемым значением.