Thread: XNA using C#
View Single Post
Old 05-05-2008, 06:29 AM   #138 (permalink)
Fog
Registered User
 
Join Date: Feb 2006
Posts: 1,657
+5 Internets
Quote:
Originally Posted by slitz View Post
Aha now I see what you mean (after reading up on it), you meant it's part of the .NET framework.
Though, one should notice that delegate / event is part of the Observable role, but yes that role should indeed be replaced by delegate / events in .NET and not implement it explicitly when using .NET.
I still don't think it's misleading however, since you kind of need to know the pattern to understand what delegate / events means in .NET
But the point still stands, it's a good situation where a Observer/Subject pattern should be used, whether it's with using delegate/events as in .NET or Subject/Observer in Java.
Yes, that's what I meant. I agree it's the right idea -- it would just be very silly to implement your own objects like that in C# when it's built into the language.

Quote:
Originally Posted by Kargon View Post
Able to show us some code example that implements the same sort of functionality?
Sure, with the caveat that I don't know Java, so I might have conceivably missed some subtlety in the posted snippet. Here's what I get out of it: you have a Subject class and associated object. It keeps a list of (abstracted) objects that want to be notified of some things that happen, and provides a mechanism to notify them all of something at the same time.

In C#, the subject class is analogous to a delegate, which is a built-in type. A delegate operates in a similar way to a function pointer (or rather, an ordered list of function pointers.) When you invoke it, it calls all of the functions in its list. For example, I could write:

Code:
... /* delegates are strongly typed, this line is just a type declaration, not an * object! they can have non-void return types, too, but then they can only * refer to one function at a time (for obvious reasons) */ public delegate void ErrorHandler(string errorMessage); public static void WriteToFile(string str) { ... } public static void WriteToScreen(string str) { ... } public static void ReportError() { // this is the object: ErrorHandler simpleDelegate = null; // the += and -= notation is overloaded in C#, // it means "add/remove from a delegate's invocation list" simpleDelegate += new ErrorHandler(WriteToFile); simpleDelegate += new ErrorHandler(WriteToScreen); // invoking the delegate, as if it were a function simpleDelegate("Here's some error text."); } ...
(Trying to clarify things through comments for people who don't know C#.)

In this example, the delegate calls both WriteToFile() and WriteToScreen() with the argument "Here's some error text."

Delegates are used directly as part of the C# event model. When you declare an event, you associate it with a delegate, which keeps a list of who is subscribed to the event. Instead of trying to explain exactly how events interact with delegates, I'll just write some code, and it should mostly speak for itself. This should be analogous to the Java subject/observer code above. Every time the spaceship hits an asteroid, it will fire off a damage-taken event, and it will let the UI know about it.

Code:
... public class SpaceShip { // delegate type declaration for event handlers of this event: public delegate void DamageTakenHandler(SpaceShip ship, float amount); // the event itself: public event DamageTakenHandler DamageTaken; /* this method is what the class uses to fire the event. it just sees * if the event delegate is null (i.e. if there are subscribers) and if * there are, it fires the event; that is, invokes the delegate. */ protected void OnDamageTaken(SpaceShip ship, float amount) { if(DamageTaken != null) DamageTaken(ship, amount); } ... ... protected void GetHitByAsteroid() { OnDamageTaken(this, 50.0); } } public class UIHealthDisplay { public void DisplayDamageTaken(SpaceShip target, float amount) { ... // do UI stuff etc } public void RegisterSpaceshipOnUI(SpaceShip ship) { /* subscribe to the event by adding your event handling * function to the event's invocation list, like so: */ ship.DamageTaken += new SpaceShip.DamageTakenHandler(DisplayDamageTaken); /* if you wrote a "DeregisterSpaceshipOnUI" function, it would * just use the "-=" operator in the same way to remove it from * the invocation list of the spaceship's damage event. */ } } ...
Obviously, you could sign lots of methods up in the same way to subscribe to that event.

Hope this satisfies folks' curiosity. C# is a pretty handy language.

Last edited by Fog : 05-05-2008 at 10:34 AM.
Fog is offline   Reply With Quote

 
Uberguilds Network