Как в C# передать указатель на функцию в конструктор класса?
От: Glorious Россия  
Дата: 29.07.05 14:16
Оценка:
Господа, тут следующая проблема :

Есть нетоторый класс Service, который предоставляет метод Call. И есть некоторый класс Proxy, в котором тоже есть метод Call и этот метод должен вызывать Call из класса Service. Для этого, в классе Proxy есть объект-делегат. Все нормально работает, но только этот делегат приходится создавать явно, обращаясь напрямую к члену класса.
Вопрос: Можно ли сделать так, чтобы этот объект создавался в конструкторе при создании экземпляра класса ? Просто более глупые программисты, использующие эти классы, очень часто забывают создавать этот член-делегат, после чего они получают кучу странных ошибок во время выполнения. Если бы можно создавать делегат в конструкторе класса, передавая ему (конструктору) в качестве параметра функцию, которую должен вызывать делегат, то такие ошибки отлавливались бы еще на стадии компиляции.

Привожу пример программки, которая всё это иллюстрирует :


class Proxy
    {    
        public delegate void CallDelegate(string str);
        public CallDelegate m_CallProxy; // это тот самый член-делегат :))
    
            public void Call(string str) // это вызов функции-делегата
        {
            m_CallProxy(str);
        }
    }
    
    class Service
    {
        // а это функция, которую нужно вызвать
                 public void Call(string str)
        {
            Console.WriteLine("WebServ.str =\"{0}\"",str);
        }
    }
    
    
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
                    
            Service srv = new Service();
            Proxy proxy = new Proxy();
                    
                   // Член - делегат создается непосредственно !
                        
            proxy.m_CallProxy = new  CSharpConsoleTestProject.Proxy.CallDelegate(srv.Call);
       
            proxy.Call("Proxy call");

            while(true);

        }
    }


Вопрос — как можно ли сделать что-нибудь, типа Proxy proxy = new Proxy(srv.Call) ?
Если делать напрямую, то C#-компилятор ругается (думает, что
srv.Call — это вызов функции, но без скобок :))
Или методы в качестве параметров можно передавать только в класс System.Delegate ?

Заранее всем спасибо !
Re: Как в C# передать указатель на функцию в конструктор кла
От: Hobot Bobot США  
Дата: 29.07.05 14:20
Оценка:
А почему не передавать в конструктор делегат собственно?
What a piece of work is a man! how noble in reason! how infinite in faculty! in form and moving how express and admirable! in action how like an angel! in apprehension how like a god! the beauty of the world! the paragon of animals!
Re: Как в C# передать указатель на функцию в конструктор кла
От: Александр Сергеевич Россия  
Дата: 29.07.05 14:21
Оценка:
Попробуй, я не смотрел правда, просто в голову пришло, написать так: MyConstructor(Delegate d) {...}
/* silent */
Re: Как в C# передать указатель на функцию в конструктор кла
От: xexe2  
Дата: 29.07.05 14:21
Оценка: -1
MethodInfo methodCall = typeof(Service).GetMethod("Call");
methodCall.Invoke("Calling///");
ну вроде и все:)
Как в C# передать указатель на функцию в конструктор класса?
От: Аноним  
Дата: 29.07.05 14:24
Оценка:
Делегаты для таких надобностей существуют.
----
В моём WMP


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Как в C# передать указатель на функцию в конструктор кла
От: Аноним  
Дата: 29.07.05 14:37
Оценка:
Здравствуйте, Glorious, Вы писали:

[skip,,]

Да, можно передать. Объявляешь делегата

public delegate void FooDelegate();


и дальше конструктор:

public MyClass(FooDelegate callback)
{
   if(callback == null)
       throw new ArgumentNullException("callback");

   [skip...]
}


ps: Может я чего не понял, но как определить эту ошибку на этапе компиляции? Вот в момент создания класса таким забывчивым программистом вылетит конечно исключение. Можно воспользоваться наследованием и абстрактным методом, но это не всегда — классы клиенты могут уже что-то другое наследовать... короче
Re[2]: Как в C# передать указатель на функцию в конструктор
От: xexe2  
Дата: 29.07.05 14:39
Оценка: :))
хм.... а где оценку ставить?
почему я не могу не согласиться сам собой?
ну вроде и все:)
Re[3]: Как в C# передать указатель на функцию в конструктор
От: GarryIV  
Дата: 29.07.05 20:05
Оценка:
Hello, xexe2!

x> хм.... а где оценку ставить?

x> почему я не могу не согласиться сам собой?

Получите и распишитесь. Всегда рад помочь

PS: Могу и убрать ты только скажи
Posted via RSDN NNTP Server 1.9
WBR, Igor Evgrafov
Re: Как в C# передать указатель на функцию в конструктор кла
От: Alvin  
Дата: 30.07.05 01:53
Оценка:
Здравствуйте, Glorious, Вы писали:

G>Вопрос — как можно ли сделать что-нибудь, типа Proxy proxy = new Proxy(srv.Call) ?

Замечу, что в C# 2.0 это работает при наличии конструктора Proxy(CallDelegate cd)
Re: Как в C# передать указатель на функцию в конструктор кла
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.07.05 12:11
Оценка:
Здравствуйте, Glorious, Вы писали:

G>Вопрос — как можно ли сделать что-нибудь, типа Proxy proxy = new Proxy(srv.Call) ?

Естественно, вот так:
class Proxy
    {    
        public delegate void CallDelegate(string str);
        public event CallDelegate m_CallProxy; // крайне не рекомендуется давать к этому члену такой доступ. Вполне хватит и +=/-=.
        public void Call(string str) // это вызов функции-делегата
        {
                    if (m_CallProxy) // очень рекомендуется делать так. Ибо иначе все упадет, если все отписались.
            m_CallProxy(str); 
        }
                public Proxy(CallDelegate d)
                {
                    m_CallProxy = d;
                }
    }
    
    class Service
    {
        // а это функция, которую нужно вызвать
                 public void Call(string str)
        {
            Console.WriteLine("WebServ.str =\"{0}\"",str);
        }
    }
    
    
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
                    
            Service srv = new Service();
            Proxy proxy = new Proxy(new Proxy.CallDelegate(srv.Call));
            proxy.Call("Proxy call");
            while(true);
        }
    }

G>Если делать напрямую, то C#-компилятор ругается (думает, что
G>srv.Call — это вызов функции, но без скобок
G>Или методы в качестве параметров можно передавать только в класс System.Delegate ?
Вплоть до .Net 2.0 — да. Но зачем? Твоя задача — сделать сигнатуру конструктора такой, чтобы не передать в нее делегат было нельзя. А уж некоторая некрасивость здесь не страшна!
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Господа, всем большое спасибо !
От: Glorious Россия  
Дата: 01.08.05 05:33
Оценка:
Благодарю всех за ответы !
Тов. Sinclair очень точно переформулировал мой вопрос — действительно, надо было создать такую сигнатуру конструктора, чтобы не передать в нее делегат было нельзя. Пока попробую использовать именно его решение — хотя после C/C++ оно может выглядеть несколько неизящно :))
Но в данном случае, главное не изящность, а эффективность !

Еще раз всем спасибо ! :up:
Re[4]: Как в C# передать указатель на функцию в конструктор
От: xexe2  
Дата: 01.08.05 06:29
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>Hello, xexe2!


x>> хм.... а где оценку ставить?

x>> почему я не могу не согласиться сам собой?

GIV>Получите и распишитесь. Всегда рад помочь


GIV>PS: Могу и убрать ты только скажи


не надо ничего убирать
это объективная оценка

далее, за минусиками, буду обращаться только к вам гарри...
ну вроде и все:)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.