Home > Back-end >  Referencing a delegate via another delegate in C#
Referencing a delegate via another delegate in C#

Time:07-14

Suppose that my namespace has 2 delegates:

public delegate void D1(string s);
public delegate void D2(string s);

They are implemented in a static class StClass like this:

public static D1 myD1 { get; set; }
public static D2 myD2 { get; set; }

In each instance of a separate non-static class MyClass I would like to include a delegate that points to one of the 2 static delegates as determined by the constructor. So I would have:

public class MyClass
{
   public delegate void D(string s);
   public D myD { get; set; }
   
   public MyClass()
   {
      if()
      {
         myD = StClass.myD1 //this assignment won't work
      }
      else
      {
         myD = StClass.myD2
      }
}

I get that I cannot directly link myD to myD1 or myD2 the way it's shown above because from the compiler's standpoint they are instances of different delegate types, but I figure since they all share the same signature there should be a simple way to achieve this. What am I missing?

CodePudding user response:

As per comments, it would probably be better to avoid declaring multiple delegate types with the same signature like this.

However, if you absolutely have to, you can convert them like this:

myD = new D(StClass.myD1);

Note that this uses the value of StClass.myD1 at the time of assignment. If you want to dynamically observe any changes in StClass.myD1, you could use a lambda expression instead:

myD = s => StClass.myD1(s);

This will evaluate the StClass.myD1 property on each invocation.

CodePudding user response:

You start by saying "Suppose that my namespace has 2 delegates:"

public delegate void D1(string s);
public delegate void D2(string s);

But, that's not what you are showing. You are showing the declaration of two, different Delegate Types. You still haven't declared a delegate yet.

Then, within your class, you declare a third delegate type, and an instance of that type:

public delegate void D(string s);
public D myD { get; set; }

Now you start trying to assign delegates of one type to another. That's never going to work; two delegate types, even if their definition completely agrees, remain distinct types. Somewhere, @EricLippert has a blog entry that explains this in detail (but, after a quick search, I can't find it). The pair of types that show this that most C# programmers are familiar with (and curse at) are:

delegate bool Predicate<in T>(T obj);

and

Func<T, bool>

The latter is used for the IEnumerable<T>.Where() extension method, while the former is used in methods like List<T>.FindAll(). Grrrr

The solution, as others have pointed out, is to use a single delegate type. Both the generic Action and Func delegates have been around for nearly forever now. I rarely define delegate types anymore, instead relying on those two types.

  •  Tags:  
  • c#
  • Related