You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中委托关联订阅方法后无法通过实例调用Click事件的问题咨询

C#委托事件示例问题排查与修正

存在的问题

  • 程序入口Main方法不符合规范:C#控制台应用的入口点必须为static静态方法,原代码定义为实例方法,程序无法正常启动。
  • 事件触发规则不符:C#中event关键字修饰的成员仅允许在声明它的类内部直接调用触发,外部类仅能执行订阅+=、取消订阅-=操作,无法直接通过myButtonObj.Click("foo")的方式在类外触发事件。
  • 缺少空值校验:直接调用委托前如果没有任何方法订阅,会触发空引用异常。
  • 缺少触发逻辑:原代码仅完成了事件订阅,没有执行触发动作,订阅的方法自然不会运行。

修正方案

标准的事件使用规范是由事件所属类提供触发方法,外部通过调用该方法间接触发事件,修正后的完整代码如下:

using System;

namespace DelegateConsoleExample
{
    public delegate void MyEventHandler(string foo);

    class Program
    {
        // 修正1:将Main改为静态入口方法
        static void Main(string[] args)
        {
            MyButton myButtonObj = new MyButton();

            myButtonObj.Click += new MyEventHandler(OnSomethingHappened_1);
            myButtonObj.Click += new MyEventHandler(OnSomethingHappened_2);

            // 修正4:调用类提供的触发方法执行事件
            myButtonObj.TriggerClick("foo");
        }

        public static void OnSomethingHappened_1(string bar)
        {
            Console.WriteLine("x method runs");
            Console.ReadKey();
        }

        public static void OnSomethingHappened_2(string bar)
        {
            Console.WriteLine("y method runs");
            Console.ReadKey();
        }
    }

    public class MyButton
    {
        MyEventHandler myField;

        public event MyEventHandler Click
        {
            add { myField += value; }
            remove { myField -= value; }
        }

        // 修正2:新增类内部的事件触发方法
        public void TriggerClick(string input)
        {
            // 修正3:空值校验,避免空引用异常
            myField?.Invoke(input);
        }
    }
}

补充说明

如果不需要事件的封装特性,仅需要可外部调用的多播委托,可以将MyButton类中的Click修改为公共委托字段,去掉event关键字和自定义的add/remove访问器,即可直接在外部调用myButtonObj.Click("foo"),但这种方式不符合事件的设计原则,不推荐在常规场景使用。

内容的提问来源于stack exchange,提问作者GNZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:27:02