【问题标题】:How to declare a singlecast delegate in C#如何在 C# 中声明单播委托
【发布时间】:2019-07-17 10:35:40
【问题描述】:

有没有办法在 C# 中声明单播委托?例如。这样就不可能在一个时间点被委托引用多个方法。

我正在考虑一种方法来实现在选择运行时使用的实现方面的灵活性,但要采取某种保护措施来防止触发多个操作以避免任何副作用,尤其是使用非 void 返回类型的委托。

【问题讨论】:

  • 你在寻找Action<T>(或者如果你想返回一些值Func<T>)?
  • AFAIK 你不能,很简单;您声明(或可能会遇到)的任何代表都将是多播的。也没有好办法检查是否有多个目标(不分配)

标签: c# .net delegates


【解决方案1】:

如果委托必须是一个事件。 (例如接口实现等)

您可以使用自定义事件访问器add/remove这仅在运行时有效,因此无法在编译时检测到。

这是一个例子:

private EventHandler _myHandler;

public event EventHandler MyHandler
{
    add
    {
        if (_myHandler != null)
            throw new InvalidOperationException("Only one eventhandler is supported");

        _myHandler = value;
    }
    remove
    {
        // you might want to check if the delegate matches the current.
        if (value == null || value == _myHandler)
            _myHandler = null;
        else
            throw new InvalidOperationException("Unable to unregister, wrong eventhandler");
    }
}

并且只是将其用作正常事件:

MyHandler += (s, ee) => Console.WriteLine("MyHandler handler");

// if you're lazy, you could support deregistering with null
MyHandler -= null;

甚至可以使用Func<T> 代替EventHandler

【讨论】:

    【解决方案2】:

    您需要封装委托的创建和分配。然后,如果有多个处理程序,您可以抛出异常。这是一个简单的例子

    using System;
    public delegate int MyDelegate(int x, int y);
    
    public class Wrapper{
        private MyDelegate d;
        public Wrapper(){
            this.d = null;
        }
        public void Assign(MyDelegate func){
            if(d!= null && d.GetInvocationList().Length > 0){
                throw new Exception("No more than 1 handlers allowed");
            }
            Console.WriteLine("Assigned");
            this.d+= func;
        }
    }
    public class Program
    {
        static int Sum(int x, int y)
        {
            return x + y;
        }
        static int Difference(int x, int y)
        {
            return x - y;
        }
        public static void Main()
        {
            Wrapper w = new Wrapper();
            w.Assign(Sum);
            w.Assign(Difference); //throws Exception;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 2011-01-12
      相关资源
      最近更新 更多