C# 通过反思引发事件

C# 通过反思引发事件,c#,reflection,C#,Reflection,我读了很多关于为什么通过反思来引发事件不可靠的帖子。。我的问题是。。我正在使用PostSharp定义一个接口,该接口允许类在属性更改前后进行通知 我创建的NotifyAttribute需要能够引发PropertyBeforeChange和PropertAfterChange事件。。问题是,即使我可以检索事件,它的GetRaiseMethod返回null,因此我无法引发所述事件。。我该怎么做呢 using PostSharp.Aspects; namespace Core { publi

我读了很多关于为什么通过反思来引发事件不可靠的帖子。。我的问题是。。我正在使用PostSharp定义一个接口,该接口允许类在属性更改前后进行通知

我创建的NotifyAttribute需要能够引发PropertyBeforeChange和PropertAfterChange事件。。问题是,即使我可以检索事件,它的GetRaiseMethod返回null,因此我无法引发所述事件。。我该怎么做呢

using PostSharp.Aspects;

namespace Core
{
    public delegate void PropertyBeforeChangeEventHandler(object sender, string sPropertyName, object oCurrentValue, ref object oProposedValue, ref bool bCancel);
    public delegate void PropertyAfterChangeEventHandler(object sender, string sPropertyName, object oOldValue, object oNewValue);

    public interface INotify
    {
        event PropertyBeforeChangeEventHandler PropertBeforeChange;
        event PropertyAfterChangeEventHandler PropertyAfterChange;
    }

    [Serializable]
    public sealed class NotifyAttribute : LocationInterceptionAspect, IInstanceScopedAspect
    {
        bool _NotifyBefore { get; set; }
        bool _NotifyAfter { get; set; }

        public NotifyAttribute() { _NotifyAfter = true; }
        public NotifyAttribute(bool bNotifyBefore, bool bNotifyAfter) { _NotifyBefore = bNotifyBefore; _NotifyAfter = bNotifyAfter; }

        public override void OnSetValue(LocationInterceptionArgs args)
        {
            INotify oNotify = args.Instance as INotify;
            if (oNotify == null) return;

            object oCurrentValue = args.GetCurrentValue();
            object oProposedValue = args.Value;
            if (object.Equals(oCurrentValue, oProposedValue)) return;
            bool bCancel = false;

            if (_NotifyBefore)
            {
                var oObj = args.Instance.GetType().GetEvent("PropertyBeforeChange");
                // RAISE EVENT HERE
            }
            if (bCancel) return;

            args.Value = oProposedValue;
            args.ProceedSetValue();
            if (_NotifyAfter)
            {
                var oObj = args.Instance.GetType().GetEvent("PropertyAfterChange");
                // RAISE EVENT HERE
            }
        }

        public object CreateInstance(AdviceArgs adviceArgs) { return this.MemberwiseClone(); }
        public void RuntimeInitializeInstance() { }
    }
}
定义了这个接口和这个属性之后,我可以如下使用它

    public class Test : INotify
    {
        public event PropertyBeforeChangeEventHandler PropertyBeforeChange;
        public event PropertyAfterChangeEventHandler PropertyAfterChange;

        [Notify]
        public string Name { get; set; }
    }

    Test oTest = new Test();
    oTest.PropertyBeforeChange += Test_PropertBeforeChange;
    oTest.PropertyAfterChange += Test_PropertyAfterChange;
    oTest.Name = "Asim";
    void Test_PropertBeforeChange(object sender, string sPropertyName, object oCurrentValue, ref object oProposedValue, ref bool bCancel)
    {
    }
    void Test_PropertyAfterChange(object sender, string sPropertyName, object oOldValue, object oNewValue)
    {
    }

您正在使用PostSharp。现在你有两个问题。你能至少解释一下你为什么要用它吗?INotifyPropertyChange是.NET编程中一个成熟的接口。可能重复:INotifyPropertyChange接口在我看来非常不合适。。1.它不提供在属性更改之前触发的事件,因此可以取消/修改更改。。如果查看oTest.Name=Asim下面的Test_PropertyBeforChange处理程序;行中,您可以看到它允许查看当前值、可在函数中更改的建议值以及也可更改的取消标志。。在NotifyAttribute类的OnSetValue函数中,这些更改的值用于设置有问题的属性,或完全取消更改。cont。2.INotifyPropertyChanged接口强制用户在每个属性的setter中显式提升OnPropertyChanged。。使用PostSharp属性,我只需要用[Notify]属性标记一个属性,它会生成代码来完成这项工作。。3.INotifyPropertyChange Interface传递给处理程序的EventArg非常通用,包含的有用信息很少。。当然,我可以使用技巧来发送更多的数据属性旧值和新值等,但让我自己的事件以局部变量的形式传递详细信息似乎是一个更好的选择=我只需要了解如何通过反思引发事件@前夕是的,我确实看到了你链接的线程。。我不明白如何在代码中实现被接受的答案所建议的。。对于下面被接受的答案,我不明白为什么我需要多播代理,甚至不知道他们是什么。。这就是我来这里寻求帮助的原因=