System.Reflection.EventInfo类的EventHandlerType属性被声明为返回可为空的Type?:

EventInfo.EventHandlerType Property

public virtual Type? EventHandlerType { get; }

当然,任何事件都必须有类型--那么为什么返回值可以为空呢?

如果我判断实现的反汇编,我想我看到它不能返回空:

namespace System.Reflection.TypeLoading
{
    /// <summary>
    /// Base class for all EventInfo objects created by a MetadataLoadContext.
    /// </summary>
    internal abstract partial class RoEvent : LeveledEventInfo
    {

        public sealed override Type EventHandlerType => _lazyEventType ?? (_lazyEventType = ComputeEventHandlerType());
        protected abstract Type ComputeEventHandlerType();
        private volatile Type? _lazyEventType;

它与类似的属性不同,比如FieldInfo.FieldTypeMethodInfo.ReturnType,它们返回Type而不是Type?.

推荐答案

让我们来看看the source for EventInfo.EventHandlerType:

public virtual Type? EventHandlerType
{
    get
    {
        MethodInfo m = GetAddMethod(true)!;
        ReadOnlySpan<ParameterInfo> p = m.GetParametersAsSpan();
        Type del = typeof(Delegate);
        for (int i = 0; i < p.Length; i++)
        {
            Type c = p[i].ParameterType;
            if (c.IsSubclassOf(del))
                return c;
        }
        return null;
    }
}

它的工作方式是获取事件的add方法,枚举其参数,并返回从Delegate继承的第一个方法.如果找不到,则返回NULL.

现在,C#永远不会让您使用不带任何委托参数的add方法来声明事件:

public event EventHandler? MyEvent
{
    add { /* value _must_ be of type EventHandler */ }
    // remove goes here 
}

正如您在上面看到的,add%方法接受与事件的委托类型相同类型的单个参数,名为value.这就是C#中的一贯方式.

但也许其他语言的工作方式有所不同.也许运行库并不关心.无论哪种方式,从反射API的Angular 来看,任何事情都可能发生.因此,它可能返回NULL.

如果您知道您正在判断哪些事件,并且知道它们都是在C#中声明的,那么您可以假定它们永远不会为空.

Csharp相关问答推荐

System.Data.SQLite:判断SQLite数据库是否为空(任何表中至少有一行)

等待限制选项似乎不适用于频道

下拉图片点击MudBlazor

react 式扩展连接中的非交叉LeftDurationTimeout

ASP.NET核心结果.文件vs结果.流

如何使用ConcurentDictionary属性上的属性将自定义System.Text.Json JsonConverter应用于该属性的值?

需要澄清C#的Clean Architecture解决方案模板的AuditableEntityInterceptor类

XUNIT是否使用测试数据的源生成器?

使用预定义对象减少Task.Run/Factory.StartNew中的关闭开销

用C#从Word文档中删除重复的节控件和文本内容控件

Blazor Web App WASM的两个独立项目令人困惑

EF核心区分大小写的主键

具有类型识别的泛型方法

我可以强制System.Text.Json.JsonSerializer以非递归方式工作吗?

如何在C#中从MongoDB IPipelineStageDefinition中获取聚合命令的字段/选项?

使用免费的DotNet库从Azure函数向Azure文件共享上的现有Excel文件追加行

在.Net 8 Visual Studio 2022中启用本机AOT发布时发布失败

读取测试项目中的应用程序设置

为什么我的UserControl没有加载到我的主窗口中?

初始化具有EntityFrameworkCore和不同架构的数据库时引发System.MissingMethodExcept