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

后端 未结 3 905
北海茫月
北海茫月 2020-12-19 09:30
class Test
{
    public delegate void FruitDelegate(Fruit f);

    public void Notify(Action del) where T : Fruit
    {
        FruitDelegate f = d         


        
相关标签:
3条回答
  • 2020-12-19 10:06

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

    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>
        }
    }
    

    That would definitely not work, so the compiler is correct here.

    0 讨论(0)
  • 2020-12-19 10:12

    What about something like this?

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

    The FruitDelegate instance, when invoked, would throw an InvalidCastException if, say, an AppleHandler was invoked with a Banana argument.

    0 讨论(0)
  • 2020-12-19 10:20

    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);
    }
    
    0 讨论(0)
提交回复
热议问题