Создание типа делегата внутри метода

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