C# 在实例化拥有该函数的对象之前分配'delegate'函数

C# 在实例化拥有该函数的对象之前分配'delegate'函数,c#,.net,generics,dynamic,delegates,C#,.net,Generics,Dynamic,Delegates,我正在开发一个系统,其中可以设置一个观察者,使其对事件感兴趣,并在传入正确类型的事件时调用操作 现在,操作在调用时需要有关事件的信息 在下面的代码中,我将委托用作操作属性(不是.NET方式的属性,只是字段/成员/任何…),在设置观察者时,我将事件函数传递给这些属性 当然,代码的问题是,在//步骤3,当我这样做时,TheEvent字段为空。只有当观察者通过事件时,才会知道它 在分配事件之前,如何让观察者执行操作从事件获取所需的属性 namespace ConsoleApplication1 { u

我正在开发一个系统,其中可以设置一个
观察者
,使其对
事件
感兴趣,并在传入正确类型的
事件时调用
操作

现在,
操作
在调用时需要有关
事件的信息

在下面的代码中,我将委托用作
操作
属性(不是.NET方式的属性,只是字段/成员/任何…),在设置
观察者时,我将事件函数传递给这些属性

当然,代码的问题是,在//步骤3,当我这样做时,
TheEvent
字段为空。只有当
观察者
通过
事件
时,才会知道它

在分配
事件
之前,如何让
观察者
执行
操作
事件
获取所需的属性

namespace ConsoleApplication1
{
using System;

internal class Program
{
    static void Main(string[] args)
    {
        //Step1: choose the IEvent: NumericEvent
        //Step2: create Watcher<NumbericEvent>
        Watcher<NumericEvent> aWatcher = new Watcher<NumericEvent>();

        //Step3: Choose and add an action
        aWatcher.TheAction = new AlphaAction();

        //Step3 bind the ActionProperties
        aWatcher.TheAction.AnActionPropertyA = aWatcher.TheEvent.GetProperty1;
        aWatcher.TheAction.AnActionPropertyB = aWatcher.TheEvent.GetProperty2;


        //Step4 Bind the event
        NumericEvent anEvent = new NumericEvent();
        aWatcher.Call(anEvent);


    }
}

internal class AlphaAction
{
    internal delegate string ActionPropertyA();
    internal delegate int ActionPropertyB();

    internal ActionPropertyA AnActionPropertyA;
    internal ActionPropertyB AnActionPropertyB;
    internal string ActionPropertyC;

    public void Run()
    {
        Console.Write(AnActionPropertyA.Invoke());
        Console.Write(AnActionPropertyB.Invoke());
    }
}


internal interface IEvent
{
}

internal class NumericEvent:IEvent
{
    internal string EventProperty1 = "Property1";
    internal int EventProperty2 = 2;

    internal string GetProperty1()
    {
        return EventProperty1;
    }
    internal int GetProperty2()
    {
        return EventProperty2;
    }

}

internal class Watcher<T> where T:IEvent
{
    internal NumericEvent TheEvent;
    internal AlphaAction TheAction;

    internal void Call(IEvent anEvent)
    {
        TheEvent = (NumericEvent)anEvent;
        TheAction.Run();
    }
}
}
命名空间控制台应用程序1
{
使用制度;
内部课程计划
{
静态void Main(字符串[]参数)
{
//步骤1:选择IEvent:NumericEvent
//步骤2:创建观察者
Watcher aWatcher=新的Watcher();
//步骤3:选择并添加操作
aWatcher.TheAction=新的AlphaAction();
//步骤3绑定ActionProperties
aWatcher.TheAction.anaActionPropertyA=aWatcher.TheEvent.GetProperty1;
aWatcher.TheAction.anaActionPropertyB=aWatcher.TheEvent.GetProperty2;
//步骤4绑定事件
NumericEvent anEvent=新的NumericEvent();
唤醒器呼叫(anEvent);
}
}
内部集体诉讼
{
内部委托字符串ActionPropertyA();
内部委托int ActionPropertyB();
内部行为财产A行为财产A;
内部行为属性b行为属性b;
内部字符串ActionPropertyC;
公开募捐
{
Write(AnActionPropertyA.Invoke());
Write(AnActionPropertyB.Invoke());
}
}
内部接口事件
{
}
内部类NumericEvent:IEvent
{
内部字符串EventProperty1=“Property1”;
内部int-EventProperty2=2;
内部字符串GetProperty1()
{
返回事件属性1;
}
内部int GetProperty2()
{
返回EventProperty2;
}
}
内部类观察程序,其中T:IEvent
{
内部数字事件;
内α作用;
内部无效调用(IEvent anEvent)
{
TheEvent=(NumericEvent)一个事件;
TheAction.Run();
}
}
}
也许需要采取一种完全不同的方法,但我希望这能解决问题并获得预期的结果


更新

我使用Delegate.CreateDelegate()进行了一些编程,但它仍然不太正确,因为它在赋值时将其视为静态(如果为null):

命名空间控制台应用程序1 { 使用制度; 运用系统反思

internal class Program
{
    static void Main(string[] args)
    {

        //Step1: choose the IEvent: NumericEvent
        //Step2: create Watcher<NumbericEvent>
        Watcher<NumericEvent> aWatcher = new Watcher<NumericEvent>();

        //Step3: Choose and add an action
        aWatcher.TheAction = new AlphaAction();

        //Step3 bind the ActionProperties

        MethodInfo method1 = typeof(NumericEvent).GetMethod("GetProperty1");
        aWatcher.TheAction.AnActionPropertyA = (AlphaAction.ActionPropertyA)Delegate.CreateDelegate(typeof(AlphaAction.ActionPropertyA), aWatcher.TheEvent, method1);

        MethodInfo method2 = typeof(NumericEvent).GetMethod("GetProperty2");
        aWatcher.TheAction.AnActionPropertyB = (AlphaAction.ActionPropertyB)Delegate.CreateDelegate(typeof(AlphaAction.ActionPropertyB), aWatcher.TheEvent, method2);

        //Step4 an event is created and passed to the Watcher
        NumericEvent anEvent = new NumericEvent("bla",3);
        if (aWatcher.GType() == anEvent.GetType())
            aWatcher.Call(anEvent);

    }
}

internal abstract class BaseAction
{
    public abstract void Run();
}

internal class AlphaAction: BaseAction
{
    internal delegate string ActionPropertyA();
    internal delegate int ActionPropertyB();

    internal ActionPropertyA AnActionPropertyA;
    internal ActionPropertyB AnActionPropertyB;
    internal string ActionPropertyC;

    public override void Run()
    {
        Console.Write(AnActionPropertyA.Invoke());
        Console.Write(AnActionPropertyB.Invoke());
    }
}


internal interface IEvent
{
}

internal class NumericEvent : IEvent
{
    private readonly string _eventProperty1;
    private readonly int _eventProperty2;

    public NumericEvent(string p1, int p2)
    {
        _eventProperty1 = p1;
        _eventProperty2 = p2;
    }

    public string GetProperty1()
    {
        return _eventProperty1;
    }
    public int GetProperty2()
    {
        return _eventProperty2;
    }

}

internal class Watcher<T> where T:IEvent
{
    internal T TheEvent;
    internal AlphaAction TheAction;

    internal Type GType()
    {
        return typeof(T);
    }

    internal void Call(IEvent anEvent)
    {
        TheEvent = (T)anEvent;
        TheAction.Run();
    }
}
内部类程序
{
静态void Main(字符串[]参数)
{
//步骤1:选择IEvent:NumericEvent
//步骤2:创建观察者
Watcher aWatcher=新的Watcher();
//步骤3:选择并添加操作
aWatcher.TheAction=新的AlphaAction();
//步骤3绑定ActionProperties
MethodInfo method1=typeof(NumericEvent).GetMethod(“GetProperty1”);
aWatcher.TheAction.AnActionPropertyA=(AlphaAction.ActionPropertyA)Delegate.CreateDelegate(类型为(AlphaAction.ActionPropertyA),aWatcher.TheEvent,方法1);
MethodInfo method2=typeof(NumericEvent).GetMethod(“GetProperty2”);
aWatcher.TheAction.AnActionPropertyB=(AlphaAction.ActionPropertyB)Delegate.CreateDelegate(类型为(AlphaAction.ActionPropertyB),aWatcher.TheEvent,方法2);
//步骤4:创建一个事件并将其传递给观察者
NumericEvent anEvent=新的NumericEvent(“bla”,3);
if(aWatcher.GType()==anEvent.GetType())
唤醒器呼叫(anEvent);
}
}
内部抽象类BaseAction
{
公开摘要无效运行();
}
内部类动作:基本动作
{
内部委托字符串ActionPropertyA();
内部委托int ActionPropertyB();
内部行为财产A行为财产A;
内部行为属性b行为属性b;
内部字符串ActionPropertyC;
公共覆盖无效运行()
{
Write(AnActionPropertyA.Invoke());
Write(AnActionPropertyB.Invoke());
}
}
内部接口事件
{
}
内部类NumericEvent:IEvent
{
私有只读字符串_eventProperty1;
私有只读int_eventProperty2;
public NumericEvent(字符串p1,int p2)
{
_eventProperty1=p1;
_eventProperty2=p2;
}
公共字符串GetProperty1()
{
返回事件属性1;
}
public int GetProperty2()
{
返回事件属性2;
}
}
内部类观察程序,其中T:IEvent
{
内部事件;
内α作用;
内部类型GType()
{
返回类型(T);
}
内部无效调用(IEvent anEvent)
{
事件=(T)事件;
TheAction.Run();
}
}

}

如果我很了解您的需要,那么您可以利用

要点如下:

  • 定义消息类型,例如
    SomeMessage
  • 在希望收到通知的位置注册此类型的消息
  • 通过发送
    SomeMessage
    的实例,可以引发“事件”
  • 将执行为此消息注册的所有操作
让我们举一个例子:

// First you create the message with the needed properties.
public SomeMessage
{
    public string Content { get; set; }
}

// Then at some places you register for listening to this type of message
Messenger.Default.Register<SomeMessage>(
    this,
    message => YourMethodThatProcessesTheMessage(message)
);

// Your method knows the exact type of the message
// So you can access all the properties of the message
private void YourMethodThatProcessesTheMessage(SomeMessage message)
{
    Console.WriteLine(message.Content);
}

// At another place you can simply send a message to all the listeners
var message = new SomeMessage() { Content = "something" };
Messenger.Default.Send<SomeMessage>(message);
//首先创建具有所需属性的消息。
公共信息
{
公共字符串内容{get;set;}
}
//然后在一些地方,你注册收听这类信息
Messenger.Default.Register(
这
message=>处理消息(message)的方法
);
//你的方法知道
internal interface IEvent { }

internal class Watcher<T> where T : IEvent
{
    internal Action<T> Action;

    public void On(IEvent evnt)
    {
        if (evnt is T) Action?.Invoke((T) evnt);
    }
}
var watcher = new Watcher<NumberEvent>();
watcher.Action += e => Console.WriteLine($"Got a number: {e.Number}");

watcher.On(new StringEvent { Text = "hello"});
watcher.On(new NumberEvent { Number = 1337});
internal class NumberEvent : IEvent
{
    internal int Number;
}

internal class StringEvent : IEvent
{
    internal string Text;
}
void Main()
{
    Watcher<NumericEvent> aWatcher = new Watcher<NumericEvent>();
    aWatcher.TheAction = new AlphaAction<NumericEvent>();
    aWatcher.TheAction.AnActionPropertyA = ne => ne.GetProperty1();
    aWatcher.TheAction.AnActionPropertyB = ne => ne.GetProperty2();
    NumericEvent anEvent = new NumericEvent("bla", 3);
    if (aWatcher.GType() == anEvent.GetType())
        aWatcher.Call(anEvent);
}

internal abstract class BaseAction<T> where T : IEvent
{
    public abstract void Run(T theEvent);
}

internal class AlphaAction<T> : BaseAction<T> where T : IEvent
{
    internal delegate string ActionPropertyA(T theEvent);
    internal delegate int ActionPropertyB(T theEvent);

    internal ActionPropertyA AnActionPropertyA;
    internal ActionPropertyB AnActionPropertyB;

    public override void Run(T theEvent)
    {
        Console.Write(AnActionPropertyA(theEvent));
        Console.Write(AnActionPropertyB(theEvent));
    }
}

internal interface IEvent
{
}

internal class NumericEvent : IEvent
{
    private readonly string _eventProperty1;
    private readonly int _eventProperty2;

    public NumericEvent(string p1, int p2)
    {
        _eventProperty1 = p1;
        _eventProperty2 = p2;
    }

    public string GetProperty1()
    {
        return _eventProperty1;
    }
    public int GetProperty2()
    {
        return _eventProperty2;
    }
}

internal class Watcher<T> where T : IEvent
{
    internal AlphaAction<T> TheAction;

    internal Type GType()
    {
        return typeof(T);
    }

    internal void Call(T theEvent)
    {
        TheAction.Run(theEvent);
    }
}