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

在抽象类中触发实体具体事件的实现方案咨询

可行实现方案

方案一:泛型自约束的ToggleEntity

将ToggleEntity改为泛型抽象类,通过自约束让基类明确具体实体类型,从而直接在通用方法中创建对应事件。

代码调整

修改基类ToggleEntity:

public abstract class ToggleEntity<T> : Entity where T : ToggleEntity<T>
{
    public DateTime? DateDeactivated { get; set; }

    public virtual void Activate()
    {
        DateDeactivated = null;
        // 构建对应实体的激活事件类型
        var eventGenericType = typeof(ActivatedEntityEvent<>);
        var concreteEventType = eventGenericType.MakeGenericType(typeof(T));
        // 创建事件实例并设置触发实体
        var activatedEvent = (EntityEvent)Activator.CreateInstance(concreteEventType);
        activatedEvent.RaisingEntity = this;
        RaiseEvent(activatedEvent);
    }

    public virtual void Deactivate()
    {
        DateDeactivated = DateTime.Now;
        // 同理处理停用事件
        var eventGenericType = typeof(DeactivatedEntityEvent<>);
        var concreteEventType = eventGenericType.MakeGenericType(typeof(T));
        var deactivatedEvent = (EntityEvent)Activator.CreateInstance(concreteEventType);
        deactivatedEvent.RaisingEntity = this;
        RaiseEvent(deactivatedEvent);
    }
}

实体子类继承时指定自身类型:

public class Foo : ToggleEntity<Foo> { }
public class Bar : ToggleEntity<Bar> { }

事件类保持原有定义即可:

public abstract class ActivatedEntityEvent<T> : EntityEvent where T : ToggleEntity<T> { }
public class FooActivatedEvent : ActivatedEntityEvent<Foo> { }
public class BarActivatedEvent : ActivatedEntityEvent<Bar> { }

核心逻辑

泛型自约束where T : ToggleEntity<T>确保T是当前实体的具体类型,基类通过typeof(T)获取实体类型,结合反射创建对应泛型事件实例,无需子类重写方法即可自动触发专属事件。


方案二:反射查找+缓存(不修改原有继承结构)

如果不想变更ToggleEntity的非泛型结构,可通过反射获取当前实例的具体类型,提前缓存实体与事件的映射关系,实现自动触发。

代码调整

修改ToggleEntity类:

public abstract class ToggleEntity : Entity
{
    // 缓存实体类型到对应事件类型的映射
    private static readonly Dictionary<Type, Type> _activatedEventMap = new();
    private static readonly Dictionary<Type, Type> _deactivatedEventMap = new();

    static ToggleEntity()
    {
        // 初始化激活事件映射
        var assembly = Assembly.GetExecutingAssembly();
        var activatedEvents = assembly.GetTypes()
            .Where(t => !t.IsAbstract 
                && t.BaseType != null 
                && t.BaseType.IsGenericType 
                && t.BaseType.GetGenericTypeDefinition() == typeof(ActivatedEntityEvent<>));
        
        foreach (var eventType in activatedEvents)
        {
            var entityType = eventType.BaseType.GetGenericArguments()[0];
            _activatedEventMap[entityType] = eventType;
        }

        // 初始化停用事件映射
        var deactivatedEvents = assembly.GetTypes()
            .Where(t => !t.IsAbstract 
                && t.BaseType != null 
                && t.BaseType.IsGenericType 
                && t.BaseType.GetGenericTypeDefinition() == typeof(DeactivatedEntityEvent<>));
        
        foreach (var eventType in deactivatedEvents)
        {
            var entityType = eventType.BaseType.GetGenericArguments()[0];
            _deactivatedEventMap[entityType] = eventType;
        }
    }

    public DateTime? DateDeactivated { get; set; }

    public virtual void Activate()
    {
        DateDeactivated = null;
        var entityType = GetType();
        if (_activatedEventMap.TryGetValue(entityType, out var eventType))
        {
            var activatedEvent = (EntityEvent)Activator.CreateInstance(eventType);
            activatedEvent.RaisingEntity = this;
            RaiseEvent(activatedEvent);
        }
    }

    public virtual void Deactivate()
    {
        DateDeactivated = DateTime.Now;
        var entityType = GetType();
        if (_deactivatedEventMap.TryGetValue(entityType, out var eventType))
        {
            var deactivatedEvent = (EntityEvent)Activator.CreateInstance(eventType);
            deactivatedEvent.RaisingEntity = this;
            RaiseEvent(deactivatedEvent);
        }
    }
}

核心逻辑

  • 静态构造函数仅执行一次,遍历程序集获取所有事件类型并缓存到字典中
  • 调用Activate/Deactivate时,通过GetType()获取当前实例的具体类型,直接从字典中查找对应事件类型
  • 创建事件实例并设置触发实体后,调用RaiseEvent完成触发

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:04:58