Awesome, nice videos
A bit of feedback/questionsâŚ
Generic Event Delegate
For your observer pattern (ie, events), if you were so inclined, you could use the more standard sender/args pattern that Microsoft uses. EventHandler has a generic type you can use so you donât have to make new delegates, just new event arg types. For exampleâŚ
class MyEventArgs : EventArgs
{
public string EventMessage { get; private set; }
public MyEventArgs(string message)
{
this.EventMessage = message;
}
}
...
class SomeObject
{
public event EventHandler<MyEventArgs> SomeEvent;
void TestEvent()
{
if (this.SomeEvent)
this.SomeEvent(this, new MyEventArgs("This is a test!"));
}
}
I donât think you have to inherit from EventArgs either, but you can to stick with how the rest of .NET sets up its events. I have found that having the sender associated with the event is helpful though.
Dangling Event Handlers
I think there might be a bit of a lifetime management issue in your code here, though Iâm not 100% sure so Iâll just bring it to your attention and you can look into it. For example, in your UI class, you pass Hero in through the constructor and have it subscribe to the OnCollect event. Now Hero is attached to the UI class, but the UI class doesnât keep a reference to Hero or unsubscribe from that event.
I think this can be an issue in cases where you want to destroy your UI object, but the Hero object sticks around. Maybe your Hero collects something and your UI changes, so you would destroy the old one and instantiate a new UI. If you were to do this, the UI object wouldnât actually destroy as the Hero object would be holding a reference to it, keeping it alive. Every time the OnCollect event fires, youâll actually get two events fired, one to the new UI object and one to the old.
To fix this, you can have your UI class keep a reference to the Hero object it was given then, in the UI objectâs destructor, unsubscribe from OnCollect.
What you have here is probably fine since the UI object is likely to live as long as the Hero object in your particular example, but I figured I would point it out since this was not obvious to me when I first learned this stuff. To be fair though, I learned this back in like .NET 2.0 so maybe some work has been done there? Either way, I figured I would mention it.
ICloneable
For your prototype example, there is an interface built into .NET called ICloneable that you could use instead of defining your own, if you wanted to. I donât think thereâs anything wrong with using your own, per se, but using the .NET one might make interacting with other built-in things that expect ICloneable a smoother experience.
Anyway, I just wanted to mention those. I love these videos, keep them up!