Ok, для ясности я собираюсь написать два снова (и немного изменить метод, чтобы сделать его короче)
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate = (a, b) =>
{
return a.RenderPartial(b);
};
public static string RenderMethod(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
}
Во-первых, обратите внимание, что RenderDelegate
(как пишет С. DePouw), просто причудливый способ с использованием синтаксиса лямбда, чтобы написать следующее:
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate =
delegate(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
};
разница между RenderMethod
и RenderDelegate
является то, что RenderMethod
представляет собой метод, RenderDelegate
является Тогда как делегат, или, более конкретно поле типа Деле Ворота. Это означает, что RenderDelegate может быть назначен.
Что такое делегат?
Делегат - это тип. От MSDN documentation: :
Делегат - это тип, который определяет подпись метода и может быть связан с любым методом с совместимой сигнатурой.
По существу вы можете представить делегата в качестве ссылки/указателя на метод, однако метод, на который указывает делегат, должен соответствовать сигнатуре, которую ожидает делегат. Так, например Func<HtmlHelper, PropertyViewModel, string>
является делегатом, что ожидает методы с подписью string MyMethod(HtmlHelper, PropertyViewModel)
и поэтому мы можем присвоить методы с этой подписью для этого делегата, как это:
RenderDelegate = RenderMethod;
важно отметить разницу между делегатом типа (отметьте капитал D) и делегат ключевое слово (нижний регистр). В вашем примере вы используете общий объект Func<>
, чтобы сконденсировать ваш код, однако его вид затушевывает то, что действительно происходит здесь. Func<HtmlHelper, PropertyViewModel, string>
является типом, который наследует от Delegate
, и вы можете использовать делегат ключевое слово delcare эквивалентный типа:
delegate string MyFunction<HtmlHelper helper, PropertyViewModel string>;
static MyFunction RenderDelegate = RenderMethod;
методов Анонимных
Когда мы назначили RenderDelegate в первом примере, мы не набор RenderDelegate Ань существующий именованный метод, вместо этого мы объявили новый метод в строке.Это известно как метод анонимного и работает, потому что мы можем передать блок кода (также объявляются с помощью делегата ключевое слово) в качестве параметра делегата:
Лямбда-функции
Назад к оригинальному синтаксису - ваш пример используя синтаксис лямбда для любознательного анонимного делегата. Лямбда-выражения - хороший способ объявить короткие встроенные методы, которые обычно можно использовать при работе со списками, например, предположим, что мы хотим отсортировать список объектов HtmlHelper по имени. Способ сделать это, чтобы передать делегат, который сравнивает два HtmlHelper объектов в метод списков сортировки, метод сортировки затем использует этот делегат для сравнения и сортировки элементов в списке:
static int MyComparison(HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name);
}
static void Main()
{
List<HtmlHelper> myList = GetList();
myList.Sort(MyComparison);
}
Чтобы избежать нагрузок короткие методы, разбросанные вокруг, вы можете использовать анонимные методы, чтобы обработать метод сортировки в строке. Что же на самом деле полезно об этом является то, что метод рядный имеет доступ к переменным, объявленным в содержащем сферу:
int myInt = 12;
List<HtmlHelper> myList = GetList();
myList.Sort(
delegate (HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name) - myInt;
});
Thats еще довольно довольно много печатать на машинке, однако, и поэтому лямбда sytax родился и теперь вам может сделать это вместо:
List<HtmlHelper> myList = GetList();
myList.Sort((x, y) => {return x.Name.CompareTo(y.Name)});
Декларирование «нормальные» методы в этом случае, однако, как представляется, совершенно бессмысленно для меня (и делает мои глаза кровоточат)
Делегаты невероятно полезны и являются (помимо всего прочего) краеугольным камнем системы событий .Net. Некоторые более чтение, чтобы очистить вещи немного:
Очень интересный вопрос, поскольку объявление «методов» таким образом делает их объектами первого класса. Вы даже можете писать методы расширения на них! – Davy8
Возможный дубликат выражения [C# Lambda, почему я должен использовать это?] (Http://stackoverflow.com/questions/167343/c-sharp-lambda-expression-why-should-i-use-this), а также [ func-delegate-vs-function] (http://stackoverflow.com/questions/3113226/func-delegate-vs-function) – nawfal