Мне было интересно, может ли кто-нибудь объяснить, что это Func<int, string>
такое и как это используется, с некоторыми ясными примерами.
Ответы:
Вы в целом знакомы с делегатами? У меня есть страница о делегатах и мероприятиях, которая может помочь, если нет, хотя она больше ориентирована на объяснение различий между ними.
Func<T, TResult>
является просто универсальным делегатом - выясните, что он означает в любой конкретной ситуации, заменив параметры типа ( T
и TResult
) соответствующими аргументами типа ( int
и string
) в объявлении. Я также переименовал его, чтобы избежать путаницы:
string ExpandedFunc(int x)
Другими словами, Func<int, string>
это делегат, который представляет функцию, принимающую int
аргумент и возвращающую string
.
Func<T, TResult>
часто используется в LINQ как для проекций, так и для предикатов (в последнем случае TResult
всегда bool
). Например, вы можете использовать a Func<int, string>
для проецирования последовательности целых чисел в последовательность строк. Лямбда-выражения обычно используются в LINQ для создания соответствующих делегатов:
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);
}
Результат:
Value=3
Value=7
Value=10
A Func<int, string>
ест целые числа и возвращает строки. Итак, что ест целые числа и возвращает строки? Как насчет этого ...
public string IntAsString( int i )
{
return i.ToString();
}
Я только что придумал функцию, которая ест целые числа и возвращает строки. Как мне это использовать?
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"
Я знаю, не очень сексуально, но это простая идея, на которой основано множество трюков. Теперь давайте воспользуемся 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
Вместо вызова IntAsString для каждого члена я создал ссылку на него с именем fnc (эти ссылки на методы называются делегатами ) и использовал ее вместо этого. (Помните, что fnc ест целые числа и возвращает строки).
Этот пример не очень привлекателен, но множество умных вещей, которые вы увидите, основаны на простой идее функций, делегатов и методов расширения .
Один из лучших грунтовок на этом материале я видел здесь . У него гораздо больше реальных примеров. :)
Это делегат, который принимает единицу int
в качестве параметра и возвращает значение типа string
.
Вот пример его использования:
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>
принимает параметр значения типа int и возвращает строковое значение. Вот пример, когда дополнительный метод поддержки не нужен.
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);
ПРИМЕЧАНИЕ. Последний тип объекта в Func (то есть «строка» в этом примере) - это тип, возвращаемый функцией (то есть не ограничивается примитивами, но любым объектом). Следовательно, Func<int, bool, float>
принимает параметры значений типа int и bool и возвращает значение с плавающей запятой.
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