How to convert an action to a specific delegate of the same signature?

class Test { public delegate void FruitDelegate(Fruit f); public void Notify<T>(Action<T> del) where T : Fruit { FruitDelegate f = del; // Cannot implicitly convert type 'Action<T>' to 'FruitDelegate } } 

Fruit is an empty class. Both of these delegates have the same signature.

I can't seem to do anything. Maybe this will help if I explain what I'm trying to do (indicate some context).

I want to create a class that has a common static method that provides the type and method of the method callback (for example, the above example).

The problem I am facing is that the delegate contains a parameter, and I do not want it to be entered in a method callback. For example, I want this:

 public void SomeMethod() { Test.Notify<Apple>(AppleHandler); } private void AppleHandler(Apple apple) { } 

Instead of this:

 public void SomeMethod() { Test.Notify<Apple>(AppleHandler); } private void AppleHandler(Fruit fruit) { Apple apple = (Apple)fruit; } 

Is it possible? Worked on it for several hours without much luck = /

+4
source share
3 answers

Is this what you want?

 static void Main(string[] args) { Program p = new Program(); p.SomeMethod(); } public class Fruit { } public class Apple : Fruit { } public delegate void FruitDelegate<in T>(T f) where T : Fruit; class Test { public static void Notify<T>(FruitDelegate<T> del) where T : Fruit, new() { T t = new T(); del.DynamicInvoke(t); } } private void AppleHandler(Apple apple) { Console.WriteLine(apple.GetType().FullName); } public void SomeMethod() { FruitDelegate<Apple> del = new FruitDelegate<Apple>(AppleHandler); Test.Notify<Apple>(del); } 
+6
source

There is a good reason why you cannot do this. Suppose the rest of your method:

 class Test { public delegate void FruitDelegate(Fruit f); public void Notify<T>(Action<T> del) where T : Fruit { FruitDelegate f = del; f(new Banana()); //should be legal, but del may be Action<Apple> } } 

This definitely won't work, so the compiler is right here.

+2
source

How about this?

 public void Notify<T>(Action<T> del) where T : Fruit { FruitDelegate f = fruit => del((T)fruit); } 

An instance FruitDelegate a call will cause an InvalidCastException, if, say, AppleHandler was called with the argument Banana .

+1
source

All Articles