Может кто-нибудь объяснить, что делает С# "Func <T, T>"?
Я читаю книгу Pro MVC 2, и есть пример создания метода расширения для класса HtmlHelper.
Вот пример кода:
public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int,string> pageUrl)
{
//Magic here.
}
И вот пример использования:
[Test]
public void Can_Generate_Links_To_Other_Pages()
{
//Arrange: We're going to extend the Html helper class.
//It doesn't matter if the variable we use is null
HtmlHelper html = null;
PagingInfo pagingInfo = PagingInfo(){
CurrentPage = 2,
TotalItems = 28,
ItemsPerPage = 10
};
Func<int, String> pageUrl = i => "Page" + i;
//Act: Here how it should format the links.
MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl);
//Assert:
result.ToString().ShouldEqual(@"<a href=""Page1"">1</a><a href=""Page2"">2</a><a href=""Page3"">3</a>")
}
Изменить: удалена часть, которая путала точку этого вопроса.
Возникает вопрос: почему в примере используется Func? Когда я должен его использовать? Что такое Func?
Спасибо!
Ответы
Ответ 1
A Func<int, string>
как
Func<int, String> pageUrl = i => "Page" + i;
- это делегат, принимающий int
как единственный параметр и возвращающий string
. В этом примере он принимает параметр int
с именем i
и возвращает строку "Page" + i
, которая просто конкатенает стандартное строковое представление i
в строку "Page"
.
В общем случае Func<TSource, TResult>
принимает один параметр, который имеет тип TSource
и возвращает параметр типа TResult
. Например,
Func<string, string> toUpper = s => s.ToUpper();
то вы можете сказать
string upper = toUpper("hello, world!");
или
Func<DateTime, int> month = d => d.Month;
чтобы вы могли сказать
int m = month(new DateTime(3, 15, 2011));
Ответ 2
Func<int, String>
означает метод обратного вызова, который принимает параметр int
и возвращает результат String
.
Следующее выражение, которое называется выражением лямбда:
Func<int, String> pageUrl = i => "Page" + i;
расширяется примерно так:
Func<int, String> pageUrl = delegate(int i)
{
return "Page" + i;
}
Ответ 3
Строка Func<int, string>
, о которой вы спрашиваете, известна как выражение лямбда.
Func<int, String> pageUrl = i => "Page" + i;
Эта строка может быть описана как функция, которая принимает параметр int (i
) и возвращает строку "Page" + i
;
Его можно переписать как:
delegate(int i)
{
return "Page" + i;
}
Ответ 4
Поскольку метод PageLinks
является методом расширения.
В методе расширения первый параметр начинается с этого ключевого слова, чтобы указать, что это метод расширения для типа, представленного первым параметром.
Func<T1, T2>
- это делегат, который представляет преобразование из типа T1
для ввода T2
. Таким образом, ваш метод PageLinks
применит это преобразование к int
для создания string
.
Ответ 5
Func<T, TResult>
: инкапсулирует метод с одним параметром и возвращает значение типа, заданного параметром TResult. Подробнее см. на этой странице и примеры.: -)
Ответ 6
У вас есть запись в блоге. Используя Func
, вы можете устранить некоторые функциональные несоответствия. Прочитайте здесь.
Ответ 7
Я реализовал метод расширения where() с помощью Func, пожалуйста, посмотрите...
public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{
foreach ( var data in a )
{
//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
if ( Method.Invoke ( data ) )
{
yield return data;
}
}
}
Вы можете использовать его, например,
foreach ( var item in Emps.Where ( e => e.Name == "Shiv" ).Select ( e1 => e1.Name ) )
{
Console.WriteLine ( item );
}
Ответ 8
Создайте свой собственный
Func<int,string> myfunc;
затем щелкните правой кнопкой мыши Func, чтобы просмотреть определение. Вы увидите, что это делегат под
public delegate TResult Func<in T, out TResult>(T arg);