всем привет, только начал изучать делегаты. Имеется вот такой пример:
// Класс, метод которого будет сообщен с делегатом.
class MyClass
{
// Создаем метод, который планируем сообщить с делегатом.
public string Method(string name)
{
return "Hello " + name;
}
}
// На 21-й строке создаем класс-делегата с именем MyDelegate,
// метод, который будет сообщен с экземпляром данного класса-делегата,
// будет принимать один строковой аргумент и возвращать строковое значение.
public delegate string MyDelegate(string name); // Создаем класс делегата. (1)
class Program
{
static void Main()
{
MyClass instance = new MyClass();
MyDelegate myDelegate = new MyDelegate(instance.Method); // Создаем экземпляр делегата и сообщаем с ним метод. (2)
string greeting = myDelegate.Invoke("djon"); // Вызываем метод сообщенный с делегатом. (3)
Console.WriteLine(greeting);
greeting = myDelegate("Grady Booch"); // Другой способ вызова метода сообщенного с делегатом. (3')
Console.WriteLine(greeting);
// Delay.
Console.ReadKey();
}
}
ради интереса заменил строку:
string greeting = myDelegate("djon"); // Вызываем метод сообщенный с делегатом. (3)
на
string greetingg = MyClass.Method("djon");
и получил следующую ошибку от Visual Studio 2012 :
Ошибка 1
Для нестатического поля, метода или свойства "Delegates.MyClass.Method(string)" требуется ссылка на объект
Ведь делегат это и есть объект, содержащий в себе указатели на методы.
Т.е этот пример с ошибкой допущенной мной ради эксперимента, и есть
наглядный или можно сказать
жизненный пример почему необходимо использовать делегаты?
Если так, то хорошо, если нет то приведите свои жизненные примеры использования делегатов.
Здравствуйте, BadCats, Вы писали:
BC>всем привет, только начал изучать делегаты. Имеется вот такой пример:
охх. Проще нормально объяснить, чем объяснить, что с объяснением выше не так.
Делегаты — это способ сделать следующее: взять произвольный кусок кода, упаковать его в объект (экземпляр делегата) и вызвать этот кусок кода в любом месте, куда получится передать ссылку на наш экземпляр делегата.
Опционально делегат может принимать параметры и/или возвращать значение, это описывается при объявлении делегата, но на сам принцип работы это никак не влияет.
собственно пример:
// Описываем и используем экземпляр делегата.
// 1. Описываем делегат.
// он будет принимать один строковый параметр, возвращать строку.
public delegate string SayHelloDelegate(string name);
// 2. Пишем код, который будет использовать наш делегат
public static void SayHelloToUsers(SayHelloDelegate sayHelloTo)
{
// Вызываем делегат
string sayHelloMessage = sayHelloTo("John");
// Выводим результат
Console.WriteLine(sayHelloMessage);
string sayHelloMessage2 = sayHelloTo("Mary");
Console.WriteLine(sayHelloMessage2);
}
// код ниже может быть расположен в другом классе или в другой сборке.
// 3. Пишем пару методов, которые создают строку приветствия для пользователя
private static string SayHello1(string name)
{
return "Алоха, " + name + "!";
}
private static string SayHello2(string name)
{
return "Добро пожаловать, " + name + "!";
}
// 4. собираем всю магию вместе.
public static void Main(string[] args)
{
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine();
Console.WriteLine("Попытка #" + i);
SayHelloDelegate sayHelloDelegate;
// бросаем монетку
if (rnd.NextDouble() < 0.5)
{
// выбрали метод 1.
sayHelloDelegate = SayHello1;
}
else
{
// выбрали метод 2.
sayHelloDelegate = SayHello2;
}
// передаём наш кусок кода в метод, откуда они будет вызван
SayHelloToUsers(sayHelloDelegate);
}
Console.ReadKey();
}
BC>Ошибка 1
BC>Для нестатического поля, метода или свойства "Delegates.MyClass.Method(string)" требуется ссылка на объект
В переводе на человеческий это означает следующее: MyClass.Method — это нестатический метод, чтобы его вызвать, надо иметь ссылку на объект типа MyClass().
т.е.
MyClass myClass = new MyClass();
...
myClass.Method("djon");
типа сработает.
Типа — потому что в реальном коде может не быть возможности напрямую передать в код ссылку на объект типа MyClass. Например, если код лежит в сборке, которая про MyClass ничего не знает.