Объяснение Func - PullRequest
       11

Объяснение Func

87 голосов
/ 18 мая 2009

Мне было интересно, может кто-нибудь объяснить, что такое Func<int, string> и как оно используется, с некоторыми наглядными примерами.

Ответы [ 4 ]

138 голосов
/ 18 мая 2009

Вы знакомы с делегатами в целом? У меня есть страница о делегатах и ​​событиях , которая может помочь, если нет, хотя она больше предназначена для объяснения различий между ними.

Func<T, TResult> - это просто общий делегат - определите, что это означает в любой конкретной ситуации, заменив параметры типа (T и TResult) соответствующими введите аргументы (int и string) в объявлении. Я также переименовал его, чтобы избежать путаницы:

string ExpandedFunc(int x)

Другими словами, Func<int, string> - это делегат, представляющий функцию, принимающую аргумент int и возвращающую string.

Func<T, TResult> часто используется в LINQ, как для проекций, так и для предикатов (в последнем случае TResult всегда равен bool). Например, вы можете использовать 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
40 голосов
/ 18 мая 2009

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 ест целые числа и возвращает строки).

Этот пример не очень сексуален, но тонна умных вещей, которые вы увидите, основана на простой идее функций, делегатов и методов расширения .

Один из лучших праймеров по этому материалу, который я видел, это здесь . У него гораздо больше реальных примеров. :)

25 голосов
/ 18 мая 2009

Это делегат, который принимает один 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();
    }
}
1 голос
/ 24 июля 2018

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

НТН

...