Есть нетоторый класс 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# передать указатель на функцию в конструктор кла
А почему не передавать в конструктор делегат собственно?
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# передать указатель на функцию в конструктор кла
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# передать указатель на функцию в конструктор
Здравствуйте, Glorious, Вы писали:
G>Вопрос — как можно ли сделать что-нибудь, типа Proxy proxy = new Proxy(srv.Call) ?
Замечу, что в C# 2.0 это работает при наличии конструктора Proxy(CallDelegate cd)
Re: Как в C# передать указатель на функцию в конструктор кла
Здравствуйте, Glorious, Вы писали:
G>Вопрос — как можно ли сделать что-нибудь, типа Proxy proxy = new Proxy(srv.Call) ?
Естественно, вот так:
class Proxy
{
public delegate void CallDelegate(string str);
publicevent 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>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Благодарю всех за ответы !
Тов. Sinclair очень точно переформулировал мой вопрос — действительно, надо было создать такую сигнатуру конструктора, чтобы не передать в нее делегат было нельзя. Пока попробую использовать именно его решение — хотя после C/C++ оно может выглядеть несколько неизящно :))
Но в данном случае, главное не изящность, а эффективность !
Еще раз всем спасибо ! :up:
Re[4]: Как в C# передать указатель на функцию в конструктор
Здравствуйте, GarryIV, Вы писали:
GIV>Hello, xexe2!
x>> хм.... а где оценку ставить? x>> почему я не могу не согласиться сам собой?
GIV>Получите и распишитесь. Всегда рад помочь
GIV>PS: Могу и убрать ты только скажи
не надо ничего убирать
это объективная оценка
далее, за минусиками, буду обращаться только к вам гарри...