如何通过抽象方法作为参考?

亚历克西娅

我承认,我正在做家庭作业,但我一直坚持这个问题(A部分)。如何通过通知方法作为铁路信号的参考?我是否只能找出抽象构造函数中调用了哪个类,然后在notify方法中打印类名称?例如:

铁路用户

private string className;

public RailwayUser()
{ 
    Type type = this.GetType();
    className = type.Name;
}

public void PrintClassName()
{
  Console.Writeline(className);
}

铁路信号类

public void Notify()
{
    foreach(RailwayUser u in _watches)
    {
        u.PrintClassName();
        u.Notice(State)
    }
}

在此处输入图片说明

柬埔寨Mrinal

This kind of code / design is flawed, since what it does is RailwayUser, registers the object reference with the _watchers List in the RailWaySignal class, which in turn calls the public Notice method on each user when Notify is invoked, which is not how Event Signaling or Function Pointer works. In fact public _watchers is dangerous, as it can be cleared by any user, though that can be moderated using property access

Code with Issue

public void Notify()
{
    foreach(RailwayUser u in _watches)
    {
        u.PrintClassName();
        u.Notice(State)
    }
}

Following shall be the actual code using events and delegates:

Correct Version

Code Snippet Online - https://www.jdoodle.com/embed/v0/uEc

void Main()
{
    List<RailwayUser> railwayUsers = new List<RailwayUser>();

    railwayUsers.Add(new RailwayUser());
    railwayUsers.Add(new RailwayUser());

    RailwayUser.TestNotification();
}

public enum Colour
{
    Red,
    Green,
    NoSignal
}

public class RailwaySignal
{
    public string Name {get; set;}

    public RailwaySignal(string railwaySignalName)
    {
        Name = railwaySignalName;
    }   

    // Delegate for handling event
    public delegate void RailwaySignalEventHandler(object source, Colour e);

    // Delagate object for handling event
    private RailwaySignalEventHandler _railwaySignalEvent;

    // Event Accessor
    public event RailwaySignalEventHandler RailwaySignalEvent
    {
        add
        {
            lock (this)
            {
                _railwaySignalEvent += value;
            }
        }

        remove
        {
            lock (this)
            {
                _railwaySignalEvent -= value;
            }
        }
    }

    // Invoke Event for subscribed clients
    private void Notify()
    {
        if (_railwaySignalEvent != null)
            _railwaySignalEvent.Invoke(this, Colour.Green);
    }

    // Test the Event Invocation
    public void TestEvent()
    {
        Notify();
    }
}

public class RailwayUser
{
    private static RailwaySignal railwaySignal { get; set;} = new RailwaySignal("Signal1");

    public RailwayUser()
    {
        railwaySignal.RailwaySignalEvent += this.Notice;        
    }

    public static void TestNotification()
    {
        railwaySignal.TestEvent();
    }

    public void Notice(object sender, Colour color)
    {       
        Console.WriteLine($"Notice Called, Colour is :: {color}, Sender is :: {((RailwaySignal)sender).Name}");
    }
}

Result

Notice Called, Colour is :: Green, Sender is :: Signal1
Notice Called, Colour is :: Green, Sender is :: Signal1

Important Details

  • Signature of the event is, (object source, Colour e) which helps in passing the relevant information across to the RailwayUser called, We now know the RailwaySignal triggering the notification to the RailwayUser and its Colour value
  • Event / Delegate has same signature as called method (which is the basis of working of Delegate / function pointers)
  • For simplification RailwayUser is a non abstract class
  • Event is executed using Notify() method inside the RailwaySignal, we are calling it artificially using TestNotification() inside RailwayUser just for demo purpose, but ideally it shall be internally triggered and shall pass on current state like Colour
  • Pre-defined delegates like Func, Action are quite often used for similar notification mechanism, They internally works using similar mechanism, though declaring an explicit event which is internally a delegate is a well defined pattern, especially for the Ui controls
  • .Net框架公开的标准事件具有签名object sender, EventArgs eEventArgs可以在其中将所有信息从事件执行器(RailwaySignal)包装到事件接收器(RailwayUser)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章