#c#
#c# #.net-2.0 #делегаты
Вопрос:
Я хочу создать тип делегата в C # внутри метода с целью создания анонимных методов.
Например:
public void MyMethod(){
delegate int Sum(int a, int b);
Sum mySumImplementation=delegate (int a, int b) {return a b;}
Console.WriteLine(mySumImplementation(1,1).ToString());
}
К сожалению, я не могу этого сделать, используя .NET 2.0 и C # 2.0.
Ответ №1:
Почему вы хотите создать тип делегата внутри метода? Что плохого в объявлении его вне метода? В принципе, вы не можете этого сделать — вы не можете объявить тип (любой тип) внутри метода.
Одной из альтернатив было бы объявить все универсальные делегаты функций / действий, которые присутствуют в .NET 3.5 — тогда вы могли бы просто сделать:
public void MyMethod(){
Func<int, int, int> mySumImplementation =
delegate (int a, int b) { return a b; };
Console.WriteLine(mySumImplementation(1,1).ToString());
}
Объявления находятся на моей странице версий C # / .NET.
Комментарии:
1. «Почему вы хотите создать тип делегата внутри метода?» — потому что единственное, что использует тип делегата, — это обратный вызов, определенный внутри метода, поэтому распространение информации, которая концептуально локальна для метода, за пределы метода кажется … неприглядным.
2. В .Net 4 вы можете написать: Func<int, int, int> mySumImplementation = (a, b) => a b;
3. @TalSegal: Это не относится конкретно к .NET 4 — это только начиная с C # 3, предназначенный для любой платформы, использующей
Func
семейство делегатов. Я подозреваю, что я использовал синтаксис анонимного метода только потому, что это сделал OP.
Ответ №2:
Тип делегата должен быть определен вне функции. Фактический делегат может быть создан внутри метода, как вы это делаете.
class MyClass {
delegate int Sum(int a, int b);
public void MyMethod(){
Sum mySumImplementation=delegate (int a, int b) {return a b;}
Console.WriteLine(mySumImplementation(1,1).ToString());
}
}
было бы допустимо.
Лучшим решением может быть эмуляция .NET3.5 и создание некоторых универсальных типов делегатов глобально, которые можно использовать во всем вашем решении, чтобы избежать необходимости постоянно переопределять типы делегатов для всего:
delegate R Func<R>();
delegate R Func<T, R>(T t);
delegate R Func<T0, T1, R>(T0 t0, T1 t1);
delegate R Func<T0, T1, T2, R>(T0 t0, T1 t1, T2 t2);
Тогда вы можете просто использовать Func<int, int, int>
делегат в вашем коде выше.
Ответ №3:
Делегаты компилируются в классы (класс, который наследуется от System.MulticastDelegate). В C # вам не разрешается объявлять класс внутри метода (см. спецификацию языка C #). Таким образом, вы также не можете объявить делегат в методе.
Ответ №4:
Как насчет этого:
static void Main(string[] args)
{
Expression<Func<int, int, int>> exFunc = (a, b) => a b;
var lambda = exFunc as LambdaExpression;
Delegate del = exFunc.Compile();
Console.WriteLine(del.DynamicInvoke(2, 2));
}