none
Как передать метод методу? RRS feed

  • Вопрос

  • Проблемный код:

            private void button1_Click(object sender, EventArgs e)
            {
                Method(Method);
            }
    
            private void Method(void myvoid)
            {
                myvoid();
            }
    По теории в данном коде будет выполняться метод бесконечно.

    5 июня 2012 г. 16:58

Ответы

  • Расширяя ответ Yatajga. У вас поле Tick имеет тип отличный от делегата Del.

    Для того, чтобы заработало, код должен выглядеть вот так:

            private void button1_Click(object sender, EventArgs e)
            {
                Method(Method2);
            }
            private void Method(EventHandler del)
            {
                del(this, new EventArgs());
                Timer timer1 = new Timer();
                timer1.Enabled = true;
                timer1.Interval = 1;
                timer1.Tick += Method2; // эта строка работает
                timer1.Tick += del;     // эта строка не работает
            }
            private void Method2(object sender, EventArgs e)
            {
                MessageBox.Show("Method2");
            }

    • Помечено в качестве ответа Ziya Ceferov 20 июня 2012 г. 11:23
    20 июня 2012 г. 11:11
    Отвечающий

Все ответы

  • Добрый день.

    В C# это называется делегаты.

    На делигаты можете посмотреть пример вот здесь.

    Ваш пример, можно записать вот так, но я думаю это будет запутанно:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Method((Action<dynamic>)Method);
        }
        private void Method(dynamic myvoid)
        {
            MessageBox.Show("Привет!");
            myvoid((Action<dynamic>)Method);
        }        
    }

    • Помечено в качестве ответа Ziya Ceferov 6 июня 2012 г. 8:27
    • Снята пометка об ответе Ziya Ceferov 6 июня 2012 г. 8:29
    • Помечено в качестве ответа Ziya Ceferov 6 июня 2012 г. 8:38
    • Снята пометка об ответе Ziya Ceferov 24 июня 2012 г. 16:29
    5 июня 2012 г. 17:08
    Отвечающий
  • Если быть точным, то метод методу не передаётся, передаётся ссылка, посредством которого можно вызвать этот метод. Метод вызывается из другого метода, напрямую или посредством ссылки(обратный вызов, если не доступен в текущем контексте). Ссылка эта: экземпляр класса-делегата, который инкапсулирует сведения о методе(основные ссылка на объект и указатель на метод), т.е полноценный объект CLR. Основной смысл делегата(можно догадаться из названия) - посредничество, механизм отделения вызываемого методаот вызывающего кода. Говоря простым языком, вызывающий знает только его, а методы к нему могут добавляться и изменяться во время выполнения, динамически.

    namespace ConsoleApplication
    {
      class Program
      {
        static void Main(string[] args)
        {
          Method1();
          //Передаём адрес метода.
          Method2(Method1);
        }
        public static void Method1()
        {
          Console.WriteLine("Hello.");
          //Используем самого себя, так он доступен в текущем контексте.
          //Что-то наподобие рекурсии, лишённое всякого смысла.
          //В конечном счёте, останов из-за переполнения стека.
          Method1();
        }
        public static void Method2(Func func)
        {
          //Используем делегат для вызова метода.
          func();
        }
        
      }
      //Что-то, наподобие указателя на функцию, за кулисами тип, 
      //инкапсулирующий данные о методе.
      public delegate void Func();
    }

    А что касается смысла Вашего кода: "По теории в данном коде будет выполняться метод бесконечно.", то там я ничего полезного не вижу, нет смысла.



    • Изменено YatajgaEditor 5 июня 2012 г. 19:27
    • Помечено в качестве ответа Abolmasov Dmitry 8 июня 2012 г. 13:53
    • Снята пометка об ответе Ziya Ceferov 24 июня 2012 г. 16:29
    5 июня 2012 г. 19:27
    Модератор
  • Почему в следующем коде строка не работает и как сделать чтобы сработала?

            public delegate void Del(object sender, EventArgs e);
    
            private void button1_Click(object sender, EventArgs e)
            {
                Method(Method2);
            }
    
            private void Method(Del del)
            {
                del(this, new EventArgs());
    
                Timer timer1 = new Timer();
                timer1.Enabled = true;
                timer1.Interval = 1;
                timer1.Tick += Method2; // эта строка работает
                timer1.Tick += del;     // эта строка не работает
            }
    
            private void Method2(object sender, EventArgs e)
            {
                MessageBox.Show("Method2");
            }

    Я так понял ошибка по причине того что делегат del не постоянный.

    Мне нужно подключить метод таймеру таким образом.

    20 июня 2012 г. 10:55
  • Вы пытаетесь передать делегату timer1.Tick другой делегат, а это не возможно.
    20 июня 2012 г. 11:01
    Модератор
  • Расширяя ответ Yatajga. У вас поле Tick имеет тип отличный от делегата Del.

    Для того, чтобы заработало, код должен выглядеть вот так:

            private void button1_Click(object sender, EventArgs e)
            {
                Method(Method2);
            }
            private void Method(EventHandler del)
            {
                del(this, new EventArgs());
                Timer timer1 = new Timer();
                timer1.Enabled = true;
                timer1.Interval = 1;
                timer1.Tick += Method2; // эта строка работает
                timer1.Tick += del;     // эта строка не работает
            }
            private void Method2(object sender, EventArgs e)
            {
                MessageBox.Show("Method2");
            }

    • Помечено в качестве ответа Ziya Ceferov 20 июня 2012 г. 11:23
    20 июня 2012 г. 11:11
    Отвечающий