我承认,我正在做家庭作业,但我一直坚持这个问题(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)
}
}
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
(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 valueRailwayUser
is a non abstract classNotify()
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 ColourFunc
, 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 controlsobject sender, EventArgs e
,EventArgs
可以在其中将所有信息从事件执行器(RailwaySignal)包装到事件接收器(RailwayUser)本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句