В нескольких словах, что может быть сказано о Func <>

Я видел Func <> для когда-то теперь, и я имею, умеют избежать его (на данный момент). Но, теперь похоже, что я не могу избежать его навсегда. Например, я попробовал Динамический Linq, но почти все было с точки зрения Func <>. Я попробовал одну из своей книги (C# 2008/Deitel&Deitel) и также MSDN, но я еще не получаю его. Они все переходят прямо в предмете.

  1. Что может быть сказано (в нескольких словах) о Func <>
  2. Я могу получить некоторые ссылки на сеть, которая могла запустить меня по тому вопросу?

Спасибо за помощь

20
задан Metro Smurf 18 April 2010 в 16:06
поделиться

7 ответов

Func <> - это общий делегат - его просто очень удобно использовать, потому что вам не нужно создавать собственный делегат для каждого Комбинация аргумент / возвращаемый тип.
Раньше вам приходилось писать что-то вроде:

public delegate long MyDelegate( int number );

public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}

Вы должны были опубликовать свой делегат, чтобы пользователь мог правильно вызвать ваш метод. Особенно, когда вам нужна куча разных делегатов, вы в конечном итоге публикуете по одному для каждого списка аргументов и типа возвращаемого значения.
С Func <> вы просто пишете:

public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
    foreach( var number in list )
    {
        myDelegate( number );
    }
}

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

Конечно, вы также можете использовать более длинные списки параметров: Func по-прежнему будет возвращать значение long , хотя для этого потребуется два int и значение bool . Если вам нужен делегат без возвращаемого значения, вам нужно будет использовать Action <> , у которого будет void в качестве возвращаемого типа.

РЕДАКТИРОВАТЬ (по запросу): Как вызвать метод в моем примере :

Для вызывающей стороны нет разницы между решением с MyDelegate или Func <> . В обоих случаях у него есть три варианта вызова метода:

Использование лямбда-нотации (требуется C # 3.0, вероятно, лучшее решение для коротких методов):

Method( myList, i => i * i );

Используя анонимный метод (требуется C # 2.0):

Method( myList, delegate( int i )
{
    return i * i;
} );

Или используя в качестве аргумента реальный метод:

Method( myList, Square );

private static long Square( int number )
{
    return number * number;
}
33
ответ дан 29 November 2019 в 22:43
поделиться

Func <...> - это семейство типов делегатов, которые возвращают некоторое значение и принимают некоторое количество аргументов; например:

  • Func - это просто что-то, что принимает int и возвращает bool (возврат всегда в конце); например, предикат:

     int [] data = {1,2,3,4,5}; 
    var odd = data.Where (i => i% 2 == 0); {{ 1}} 
  • Func - это метод, который возвращает строку, например () => "hello world"; .

  • Func может иметь вид (when, howLong) => when + howLong;

Аналогично есть Action <...> который делает то же самое, но без возвращаемого типа.

В Func <...> нет ничего волшебного - это просто более простой способ выражения делегатов, в то время как a: с использованием универсальных шаблонов (полезно для LINQ) или b: вам не нужно искать каковы аргументы; если тип делегата непонятен (например, PipeStreamImpersonationWorker ), может быть трудно понять, что для этого нужно; если бы это было выражено как сопоставимое Action , было бы ясно, что оно не принимает никаких параметров и возвращает void .

12
ответ дан 29 November 2019 в 22:43
поделиться

Вы можете начать с 101 примеров Linq .

Короче говоря, Func <> - это делегат, в котором последний параметр типа является возвращаемым типом.

Итак, Func - это делегат, который принимает параметр int и возвращает bool .

3
ответ дан 29 November 2019 в 22:43
поделиться

Если вы когда-либо использовали оператор => в C # и, вероятно, использовали, вы уже использовали Funcs. Вы просто не объявляли их явно.

Итак, если вы пишете такой оператор, как

var peopleWhoLikeBlue = people.Where(person => person.FavoriteColor == "Blue");

, вы передаете Func в метод Where ().

Если вы хотите быть многословным, вы можете переписать это утверждение следующим образом:

Func<Person, bool> favoriteColorIsBlue = person => person.FavoriteColor == "Blue";
var peopleWhoLikeBlue = people.Where(favoriteColorIsBlue);

И вы получите тот же результат.

1
ответ дан 29 November 2019 в 22:43
поделиться

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

interface IFuncIntString
{
    string Invoke(int x);
}

То есть делегат - это объект, реализующий этот интерфейс. У него есть единственный метод Invoke, который принимает int и возвращает строку.

Теперь добавьте к этому функцию, позволяющую опустить «Вызов» при вызове, и у вас есть делегат.

10
ответ дан 29 November 2019 в 22:43
поделиться

Func (например) - это тип (аналогично тому, как строка является типом). Таким образом, вы используете его для объявления переменных, полей, параметров и так далее.

Он представляет собой вычисление, которое может быть выполнено всякий раз, когда вы запрашиваете ответ:

Func<int> f = () => DateTime.Now.Second;

// elsewhere...

Console.WriteLine( f() );

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

Func<int, string> quoteInt = n => "\"" + n + "\"";

Console.WriteLine( quoteInt(3) );

Func - это тип делегата. Вы можете объявить свой собственный, но проще использовать Func . Если вы хотите вернуть void , используйте Action вместо Func . Вам нужно только объявить настраиваемые делегаты, если вам нужны параметры out или ref .

При присвоении лямбда функции Func вы можете ссылаться на локальные переменные. Это очень мощно; это означает, что Func - это больше, чем просто код; у него есть данные. Так что это похоже на объект с одним методом (что технически так и есть - метод называется Invoke , и компилятор неявно вызывает этот метод для вас, когда вы вызываете делегат).

Синтаксис () => может быть помещен перед любым выражением, чтобы сказать «не делайте этого сейчас, отложите это на потом». Это позволяет вам инициализировать делегата, фиксирующего отложенное вычисление. И затем синтаксис () может быть помещен после делегата, чтобы фактически запустить вычисление.Таким образом, суффикс () является своего рода противоположностью префиксу () => .

7
ответ дан 29 November 2019 в 22:43
поделиться

Func <..., T> является делегатом. где T - возвращаемый тип, а все остальные - входные параметры.

1
ответ дан 29 November 2019 в 22:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: