:: Не фоксом единым
Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Можно написать так:

using System.Threading;
[...]
Thread t1 = new Thread(
() =>
{
Console.WriteLine("Hello, World!");
});
t1.Start();

Это то же самое, что:

Thread t1 = new Thread(
delegate ()
{
Console.WriteLine("Hello, World!");
});
t1.Start();

Хочу объявить свой тип делегата. Делаю:

class Program
{
delegate void MyDelegate();
static void Main(string[] args)
{
MyDelegate myDelegate = delegate()
{
Console.WriteLine("Hello, World!");
};
Thread t1 = new Thread(myDelegate); // ошибка компиляции
t1.Start();
Console.ReadLine();
}
}

Ругается:

Цитата:
Аргумент 1: не удается преобразовать из "test3.Program.MyDelegate" в "System.Threading.ThreadStart".

Почему? Можно ли исправить код, что бы работал?



Исправлено 1 раз(а). Последнее : S-type, 04.03.17 15:14
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Понятно, что если сделать:

static void MyFunc()
{
Console.WriteLine("Hello, World!");
}
static void Main(string[] args)
{
Thread t1 = new Thread(MyFunc);
t1.Start();
Console.ReadLine();
}

Всё работает. Но, хотелось бы сделать с помощью делегата.
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Так то же не работает:

delegate void MyDelegate();
static void MyFunc()
{
Console.WriteLine("Hello, World!");
}
static void Main(string[] args)
{
MyDelegate myDelegate = MyFunc;
Thread t1 = new Thread(myDelegate);
t1.Start();
Console.ReadLine();
}
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Вот так работает.

MyDelegate myDelegate = delegate()
{
Console.WriteLine("Hello, World!");
};
Thread t1 = new Thread(new ThreadStart (myDelegate));
t1.Start();




В msdn.microsoft.com сказано, что есть несколько перегруженных методов:

Thread(ParameterizedThreadStart) - Инициализирует новый экземпляр класса Thread, при этом указывается делегат, позволяющий объекту быть переданным в поток при запуске потока.

Thread(ThreadStart) - Инициализирует новый экземпляр класса Thread.

Не понятно, в чём разница между методами.

Если выполняется:

Thread t1 = new Thread(
delegate ()
{
Console.WriteLine("Hello, World!");
});
t1.Start();

Какой из методов работает? И, почему он же не работает для:

MyDelegate myDelegate = delegate()
{
Console.WriteLine("Hello, World!");
};
Thread t1 = new Thread(myDelegate);
t1.Start();



Исправлено 2 раз(а). Последнее : S-type, 04.03.17 16:02
Ratings: 0 negative/0 positive
Re: Делегат
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Ну.. за самодостаточность!.. [sm128]
Ratings: 0 negative/0 positive
Re: Делегат
SoccerStudio

Сообщений: 5055
Откуда: Подмосковье
Дата регистрации: 28.11.2006
Simple777
Ну.. за самодостаточность!.. [sm128]
Не, ну а чего, правильно. С самим собой поговорить всегда приятно, а иногда и полезно.


------------------
"Здесь я, братцы, сдержу матерщину, и скажу только "... мать!"" (с) Шаов
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Simple777
Ну.. за самодостаточность!.. [sm128]

Хм... Вопрос то "Почему?" остался. Хочется не просто, что бы работало, а понимать - почему именно так.
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Буду благодарен на ссылки, подсказки, намёки... Размер моей благодарности не будет иметь границ (В разумных пределах) (С) Задорнов.
Ratings: 0 negative/0 positive
Re: Делегат
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Всё очень печально... Надо возвращаться к основам - системе типов. Читать весь раздел мануала посвящённый делегатам.
И тогда будет понятно почему в метод ожидающий тип int нельзя передать string. Ну и, соответственно, в метод ожидающий тип ThreadStart нельзя передать тип MyDelegate...
Типы делегатов не приводятся, но в конструктор такого типа можно передать другой объект-делегат. И если они "совместимы по сигнатуре", то вновь созданный объект-делегат будет содержать "ссылку" на тот же метод (можно и анонимный), который содержался в ранее созданном объекте-делегате.
Именно поэтому работает
new Thread(new ThreadStart (myDelegate));
объект типа MyDelegate передаётся в конструктор типа ThreadStart, и т.к. они совместимы, то создаётся новый объект делегат (уже "правильного" типа для конструктора класса Thread) указывающий на тот же самый метод.
При использовании анонимного метода или лямбды происходит автоматический вывод типа, поэтому компилятор создаёт "правильный" тип делегата для данного метода.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
При использовании анонимного метода или лямбды происходит автоматический вывод типа, поэтому компилятор создаёт "правильный" тип делегата для данного метода.

Вот оно где "собака порылась".
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Читать весь раздел мануала посвящённый делегатам.

Полез читать...
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
При использовании анонимного метода или лямбды происходит автоматический вывод типа, поэтому компилятор создаёт "правильный" тип делегата для данного метода.

Вывод типа, это когда переменная неизвестного типа слева, а справа - известного. Например:

int i = 1;
var j = i; // вывод типа

А вот когда слева и справа переменные разного типа, то это "автоматическое приведение типов":

int i = 1;
float j = i; // автоматическое приведение типа

В случае

Thread t1 = new Thread(myDelegate);

Компилятор ругается:

Цитата:
Аргумент 1: не удается преобразовать из "test3.Program.MyDelegate" в "System.Threading.ThreadStart".

Может, проблема не в выводе типов, а в приведении типов?



Исправлено 2 раз(а). Последнее : S-type, 04.03.17 22:38
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
При этом msdn.microsoft.com этом описание

public delegate void ThreadStart()

Т.е. как бы очень похоже на

delegate void MyDelegate();

и, нет каких то причин "брыкаться" по поводу типов.
Ratings: 0 negative/0 positive
Re: Делегат
SoccerStudio

Сообщений: 5055
Откуда: Подмосковье
Дата регистрации: 28.11.2006
Мда..., сложно объяснить.
Ну, к примеру.
У тебя есть девушка и есть другая девушка. То, что у этих двух девушек одинаковое количество рук, ног и прочих прелестей, не делает этих двух девушек одною. Т.е. никак не приводит к заключению "нет каких-то причин брыкаться по поводу типов".
Можно, правда, сделать "приведение" - сказать что-то типа "Маша, я буду звать тебя Даша, потому что другую девушку тоже зовут Даша. Поэтому когда мы с тобой в постели кой чего делаем, это я не с тобой, а с ней."


------------------
"Здесь я, братцы, сдержу матерщину, и скажу только "... мать!"" (с) Шаов




Исправлено 2 раз(а). Последнее : SoccerStudio, 04.03.17 23:40
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Не смотря на то, что девушка это "объект", а не тип - аналогия понятна. ThreadStart и MyDelegate - это разные типы, для которых не существует автоматического приведения типа. Так?

Тогда вопрос - почему работает

Thread t1 = new Thread(
delegate ()
{
Console.WriteLine("Hello, World!");
});

Не ужели потому, что ThreadStart является дочерним для delegate?
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
delegate void Masha();
delegate void Dasha();
static void myFunc()
{
Console.WriteLine("Hello");
}
static void Main(string[] args)
{
Masha masha = myFunc;
Dasha dasha = masha; // Не удается неявно преобразовать тип "test3.Program.Masha" в "test3.Program.Dasha".
Dasha dasha = (Dasha) masha; // Не удается преобразовать тип "test3.Program.Masha" в "test3.Program.Dasha".
}

М, да... Какие то "непокладистые" делегаты. Как же преобразовать?
Ratings: 0 negative/0 positive
Re: Делегат
SoccerStudio

Сообщений: 5055
Откуда: Подмосковье
Дата регистрации: 28.11.2006
Так не надо девушек-то преобразовывать. Надо определиться, с какой гулять.


------------------
"Здесь я, братцы, сдержу матерщину, и скажу только "... мать!"" (с) Шаов
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Типы делегатов не приводятся, но в конструктор такого типа можно передать другой объект-делегат. И если они "совместимы по сигнатуре", то вновь созданный объект-делегат будет содержать "ссылку" на тот же метод (можно и анонимный), который содержался в ранее созданном объекте-делегате.

Т.е. есть только один вариант:

Masha masha = myFunc;
Dasha dasha = new Dasha(masha);
Ratings: 0 negative/0 positive
Re: Делегат
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Алгоритм Казановы:

Masha masha = myFuck;
Dasha dasha = new Dasha(masha);

[sm128]
Ratings: 0 negative/0 positive
Re: Делегат
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
При использовании анонимного метода или лямбды происходит автоматический вывод типа, поэтому компилятор создаёт "правильный" тип делегата для данного метода.

Не смог найти в нете подтверждения этому (возможно, плохо искал).

Мне кажется, что

Thread t1 = new Thread(
delegate ()
{
Console.WriteLine("Hello, World!");
});

работает потому, что ThreadStart наследуется от Delegate. Т.е. контравариантность делегата.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 5 (Гостей: 5)

© 2000-2024 Fox Club 
Яндекс.Метрика