hello everyone, just started to teach delegates. and while I understood the following:

in order to create a delegate, we first create a delegate class (yes, yes, I know that this is not an entirely correct name)

public delegate void MyDelegate(); // Создаем класс делегата. (1) 

The delegate class describes the signature of the method that we communicate (we make common from the word) with this delegate.

 // Создаем статический метод, который планируем сообщить с делегатом. public static void Method() { Console.WriteLine("Строку вывел метод сообщенный с делегатом."); } 

then, we create an instance of the delegate whose constructor accepts the method we need for the message:

 MyDelegate myDelegate = new MyDelegate(MyClass.Method); // Создаем экземпляр делегата. (2) 

since I understood if the signature of another method

 // Создаем статический метод, который планируем сообщить с делегатом. public static void MyMethod() { Console.WriteLine("Строку вывел метод сообщенный с делегатом."); } 

- matches the delegate class signature, we only need to create another delegate instance

 MyDelegate myDelegate = new MyDelegate(MyClass.MyMethod); // Создаем экземпляр делегата. (2) 

and just as a constructor parameter, pass another method with the same signature (except the name of course)

And if the signature of the method we want to communicate differs from the delegate class already existing in the program, then we need to create a new one that describes another signature of the method we need (type of returned and received values) and then an instance of this delegate class.

Ie as I understood, if the signature of two or three methods in the program is the same (except for the name), then we can simply “clip” delegates instances, each of which will be communicated with its own of these several methods. And if three methods with the same signature, and the fourth - with excellent, for this you will have to create a new delegate class.

I understand everything correctly?

  • one
    By the way, you can write shorter MyDelegate myDelegate = MyClass.Method; - Alexey Shimansky
  • 2
    Yes, as long as everything is correct, most likely further explore more practical ways to use and assign them. - Alex Krass
  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

3 answers 3

To start studying right.

Regarding the last question: true, but not in all cases: There is also Covariance and contravariantness of delegates : this refers to the types defined in the signature of the method.

In short, then:

Covariance allows you to assign a method to a delegate whose return type is a class that inherits from the class in the delegate return type.

Contravariance allows the delegate to assign a method whose parameter type is the class that is the base class for the class specified in the delegate declaration.

 class Person { public string Name { get; set; } public Person(string name) { Name = name; } public void Display() { Console.WriteLine(Name); } } class Client : Person { public Client(string name) : base(name) { } } delegate Person PersonFactory(string name); static void Main(string[] args) {    PersonFactory personDel;    personDel = BuildClient; //<-- ковариантность:    // переменной делегата типа PersonFactory    // присваивается метод, возвращаемый тип которого (Client) // является производным от базового (Person), определенного при объявлении типа делегата. //Возвращаемый тип метода: Client <- Person == ковариантность    Person p = personDel("Tom");    p.Display();    Console.Read(); } private static Client BuildClient(string name) {    return new Client(name); } delegate void ClientInfo(Client client); static void Main(string[] args) { ClientInfo clientInfo = GetPersonInfo; //<- контравариантность // идет уже по отношению к параметрам, заданным в типе делегата Client client = new Client("Alice"); clientInfo(client); Console.Read(); } private static void GetPersonInfo(Person p) { p.Display(); } 

In fact, co-countervariance is a derivative with respect to such concepts as: object of type and type of reference to object. Example:

 Person ob = new Client() // здесь мог быть прописан вызов метода //BuildClient, возвращающий объект типа Сlient 

The contravariance will be identical to the example above, except that the new Client() will be passed as a parameter to the method.

That is, if you study these concepts "head on" by the textbook, it will be much more difficult to understand their essence than to learn what is the type of object and what is the type of reference to the object (which is much more important).

This is very difficult for a beginner (and quite specific in practice). And not so difficult, right?))

  • it would be worth adding code example code / contra - Grundy
  • As I noted, it is difficult for a beginner and specific in practice, i.e. very rarely used. Here is a good example - Alex
  • With an example of code directly in the answer, the text may seem more understandable - Grundy
  • + did, I think, laid out as much as possible - Alex

You can not create a delegate and use a ready-made Action

instead of: public delegate void MyDelegate(); // Create delegate class

....

MyDelegate myDelegate = MyClass.Method; - Alexey Shimansky

write: Action myDelegate = MyClass.Method;

  • Not always delegate can be replaced with Action or Func - Grundy
  • You absolutely do not take into account that the person is only learning and the code is given exclusively in the demo versions, and also does not read the question at all. It clearly says about the use of returned and received values and a lot of interesting things. - Alex Krass
  • one
    @AlexKrass, yes this is a comment copy-paste, and along with the name and even from "1 hour ago", the unit remained. - Qwertiy
  • @Qwertiy, in addition to the “answer” itself (the first two lines), there is also an attempt to cite a comment on the question from Alexey Shimansky (the last but one line) and the “answer” to this comment (last line). - Alex Krass
  • c @Alex Krass agree, but just wanted to show the person asking the question, where else can you “dig” - Serious Orange

Everything is correct, only somehow complicated, usually delegates do not use it that way.

Most often they are used in conjunction with lambdas and expressions to implement strategies. The most typical example is the use of the linq fluent interface. Less often, but also happens - for the announcement of events.

By the way, at the initial level, it may not be necessary to know exactly how expressions work, but knowing that they differ significantly from delegates, and usually are not performed directly, but parsing and transforming into something is very useful.

Yes, and between the events and delegates the difference, on the contrary, is not as big as it seems at first glance. A delegate instance, for example, can also store references to several methods at once.

Well, yes, as already mentioned above, it is not necessary to use a constructor every time, C # can implicitly convert a method / lambda into a delegate, including instance methods, not only static ones.