Подтвердить что ты не робот

С#: Функция в функции возможна?

Можно ли объявить метод в другом методе в С#?

Например, например:

void OuterMethod()
{
    int anything = 1;
    InnedMethod();
    void InnerMethod()
    {
        int PlitschPlatsch = 2;
    }
}
4b9b3361

Ответ 1

Не прямо нет. С# не поддерживает внутренние методы. Он поддерживает анонимные методы, хотя может служить той же цели

void OuterMethod()
{
    int anything = 1;
    Action InnedMethod = () =>
    {
        int PlitschPlatsch = 2;
    };
    InnedMethod();
}

Ответ 2

UPDATE: С# 7 добавили локальные функции (https://docs.microsoft.com/en-us/dotnet/articles/csharp/csharp-7#local-functions)

void OuterMethod()
{
    int foo = 1;

    InnerMethod();

    void InnerMethod()
    {
        int bar = 2;
        foo += bar
    }

}

В версиях С# до С# 7 вы можете объявить Func или Action и получить что-то подобное:

void OuterMethod()
{
    int foo = 1;
    Action InnerMethod = () => 
    {
        int bar = 2;
        foo += bar;
    } ;

    InnerMethod();
}

Ответ 3

да, есть способы. С С# 3.0 у вас есть Func<T> тип, который делает это.

Например, я написал это вчера:

  var image = Image.FromFile(_file);
  int height = image.Height;
  int width = image.Width;
  double tan = height*1.00/width;
  double angle = (180.0 * Math.Atan(tan) / Math.PI);
  var bitmap = new System.Drawing.Bitmap(image, width, height);
  var g = System.Drawing.Graphics.FromImage(bitmap);
  int fontsize = 26; // starting guess
  Font font = null;
  System.Drawing.SizeF size;

  Func<SizeF,double> angledWidth = new Func<SizeF,double>( (x) =>
      {
          double z = x.Height * Math.Sin(angle) +
          x.Width * Math.Cos(angle);
          return z;
      });

  // enlarge for width
  do
  {
      fontsize+=2;
      if (font != null) font.Dispose();
      font = new Font("Arial", fontsize, System.Drawing.FontStyle.Bold);
      size = g.MeasureString(_text, font);
  }
  while (angledWidth(size)/0.85 < width);

Цель состояла в том, чтобы добавить водяной знак к существующему изображению. Я хотел бы сделать размер текста водяного знака примерно на 85% от ширины изображения. Но я хотел наложить текст водяного знака так, чтобы он был написан под углом. Это показало необходимость выполнения некоторых триггерных вычислений на основе углов, и я хотел немного выполнить эту работу. Func идеально подходит для этого.

В приведенном выше коде определена функция Func (функция), которая принимает SizeF и возвращает a double, для фактической ширины текста при его рисовании под заданным углом. Этот Func является переменной внутри функции, и сама переменная содержит функцию (ссылку на a). Затем я могу вызвать эту функцию "private" в пределах области, где я ее определил. Func имеет доступ к другим переменным, которые определены перед ним, в области выполнения. Таким образом, переменная angle доступна в функции angledWidth().


Если вы хотите invokable logic, которая возвращает void, вы можете использовать Action<T> таким же образом..NET определяет генераторы Func, которые принимают N аргументов, поэтому вы можете сделать их довольно сложными. Func похож на функцию VB или метод С#, который возвращает не-void; Действие похоже на VB Sub или метод С#, который возвращает void.

Ответ 4

Прошло пять лет с тех пор, как был задан этот вопрос, и теперь идет С# 7.

Он должен включать локальные функции и, по-видимому, уже реализован.

Локальные функции (Предложение: # 259) [в настоящее время в будущем филиале]

https://github.com/dotnet/roslyn/issues/259

Ответ 5

Ключевое слово delegate делает это.

void OuterMethod()
{
    var InnerMethod = delegate()
    {
        int PlitschPlatsch = 2;
    };

    int anything = 1;
    InnerMethod();
}

Не забывайте, что при определении области видимости переменная PlitschPlatsch недоступна вне InnerMethod.

Ответ 7

Если вы ищете в основном "скрыть" метод, который является всего лишь "помощником"... другим вариантом является создание вашего помощника (ов) private. Таким образом, они не становятся частью общедоступного интерфейса класса.

Это имеет то преимущество, что помощник может быть повторно использован, если необходимо; но он/они не будут "внутренними" для вызывающего метода.

Ответ 8

Да, вы можете создать метод внутри метода

void OuterMethod(){
int anything = 1;
InnedMethod();
void InnerMethod()
{
    int PlitschPlatsch = 2;
}}

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