If, lets say I have a FormA with a ListView and an Update() function. Then I also have one Math-Class with a function A() wich does some magic... Can a delegate be used to call Update() from A()? Or Is there a better way? I've realized it's risky to update a gui form from another class.... Thanks in advance!
Yes. Its not that risky as long as the Math class has no knowledge of what its actually calling. You just give it a rough idea by pointing it to the desired function from your Form:
public class MathClass {
public Action FunctionToCall { get; set; }
public void DoSomeMathOperation() {
// do something here.. then call the function:
FunctionToCall();
}
}
In your form you would do this:
// Form.cs
public void Update() {
// this is your update function
}
public void DoMathStuff() {
MathClass m = new MathClass() { FunctionToCall = Update };
m.DoSomeMathOperation(); // MathClass will end up calling the Update method above.
}
Your MathClass calls Update, but it has no knowledge of the object that told it to call Update or where Update is.. making it safer than tightly coupling your objects together.
Related
I'll start with a code example. I have a following class
public class Foo
{
public object DoSomething() {}
}
I also have some code that utilises method DoSomehting from class Foo.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
...
foo.DoSomething();
}
}
How could I distinguish those two calls foo.DoSomething() inside the Foo class?
What I came up with is to have an identification object passed in parameters for each call to DoSomething. Then in Foo class I would store the ids and compare them when new call is made.
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
var idObjA = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjA);
...
var idObjB = new IDObj(Guid.NewGuid());
foo.DoSomething(idObjB);
}
}
Maybe there is a better way to do it, or a pattern that I'm not aware of. I want the utilising code to be the least obscured so calls to the DoSomething method are as simple as possible.
To clarify my intentions. I'm implementing a message service with an ability for the user to check a checkbox on dialog box (e.g. Do not show again, or Apply to all). Code utilising the service can call the same method multiple times, to show an error message for example, but in different context. In other words, when user decided to not show that message again for particular action message box should not appear. Thus I need to know when method was called multiple times in the same context (action)
Maybe you should expand a bit on what exactly you are trying to achieve. If you're using your instantiated class like described above and are just trying to differentiate between the first and second call, you can add a respective toggle field in your Foo class:
public class Foo
{
private bool _firstCall = true;
public object DoSomething() {
if(_firstCall) {
_firstCall = false;
// first call logic
} else {
// second call logic
}
}
}
Based on the extra info in your edit, it sounds like what you perhaps need to be doing is setting a separate property in your Foo class showing whether the "apply to all" or "do not show again" option has been checked for a particular context.
Then when you call DoSomething, it can check that property to know if it should show the dialog or not.
So in the simplest case you might do something like:
public class Foo
{
public bool DoNotShow { get; set; };
public void DoSomething() {
if(this.DoNotShow == true) {
// logic
} else {
// alternative logic
}
}
}
public class Boo
{
privite Foo foo;
public void SomeMethod()
{
...
foo.DoSomething();
foo.DoNotShow = true;
...
foo.DoSomething();
}
}
The value could then be toggled on and off whenever you like.
N.B. You mentioned different "contexts" in which dialogs can be turned on and off.
For this, you could consider either giving this property the ability to store values for different contexts (e.g. in something like a Dictionary, perhaps) and then passing in the current context name to the DoSomething method when it's called. Or even pass in a totally separate "context" object to DoSomething each time, which contains the context name and the boolean indicating whether to show the dialog or not.
Or...using a different instance of Foo for each context might actually be more in line with object-oriented principles (in which case you could probably use the code exactly as per my example above). Again it depends exactly how the class the and the overall application works.
If knowing the line number of the call helps, you could use one of the methods for getting the caller information described here. So for example:
public class Foo
{
public object DoSomething() {
StackFrame frame = new StackFrame(1, true);
var method = frame.GetMethod();
var lineNumber = frame.GetFileLineNumber();
}
}
I am trying to implement C# as a scripting language for my game engine. Everything works fine, only one major problem occurred in my design.
I have the class BaseEntity. And another class BossEntity that derives from BaseEntity. Then I want to be able to create a new entity via script. So I create a class in my script let's say Boss1, that derives from BossEntity.
BaseEntity has an virtual Update Method. BossEntity overrides it and calls also base.Update(). All fine in the design.
But now to my problem. In my script I also want to be able to override the Update Method. So I go ahead and override it again. All works as supposed, the BossEntity override gets lost, as I now override the BaseEntity Update again.
But for simplicity I do not want to have to call in my script base.Update() to have the same behavior as in BossEntity. That's a thing that can be forgotten, which would be for me as for a scripting language bad design.
When scripting you just add functionality not remove some in my opinion.
So my general question is, is there any way to accomplish a call to base.Update() without even calling it extra in my script?
I assume no, or maybe just with a trick, but you never know.
As far as I know, there is no way to automatically invoke the base class's virtual method when an overridden one is invoked. You must explicitly call it.
One of the things you can do is break the parent method up a bit more. Instead of having all of the code in a single overridable method like this:
public class Foo
{
public virtual void Update()
{
// Do stuff
}
}
public class Bar : Foo
{
public override void Update()
{
// Replaces the parents implementation of the
// Update method due to not calling base.Load();
}
}
Instead, you can use the Template Method Pattern to break it up in to multiple parts, so that the user can override the part that is meant explicitly for them.
public class Foo
{
public void Update()
{
this.OnUpdating();
this.PerformUpdate();
this.OnUpdated();
}
public virtual void PerformUpdate()
{
// Leave this empty. Let the subclass override it and
// do their own thing. Your parent code will still
// get called when Update() is called.
}
public void OnUpdating()
{
// Invoke code that you want to guarantee is always
// executed PRIOR the overridden PerformUpdate() method
// is finished.
}
public void OnUpdated()
{
// Invoke code that you want to guarantee is always
// executed AFTER the overridden PerformUpdate() method
// is finished.
}
}
public class Bar : Foo
{
public override void PerformUpdate()
{
// Do custom stuff, don't have to call base.PerformUpdate()
// because it already does it's code in OnUpdating()
// and OnUpdated().
}
}
Hope this makes sense. This is what I do in my game engine. I then document that a call to base.PerformUpdate() is not needed. Another option is to make the PerformUpdate() method abstract, forcing children to implement it. That makes it a bit more clearer that there is no need to invoke base.PerformUpdate().
public class Foo
{
public void Update()
{
this.OnUpdating();
this.PerformUpdate();
this.OnUpdated();
}
// Child class is required to implement this method.
// Only downside is you will no longer be able to instance
// the base class. If that is acceptable, then this is really
// the preferred way IMO for what you are wanting to do.
public abstract void PerformUpdate();
public void OnUpdating()
{
// Invoke code that you want to guarantee is always
// executed PRIOR the overridden PerformUpdate() method is finished.
}
public void OnUpdated()
{
// Invoke code that you want to guarantee is always
// executed AFTER the overridden PerformUpdate() method is finished.
}
}
In the end, this approach lets your base class handle its update code safely, by forcing children to implement their own update method that you do not depend on. Your base class can run through its update stuff before and after the child-class has run through its updates.
This basically lets you do this in your game code:
Bar myFoo = new Bar();
myFoo.Update();
And you can rest assured that your base class update methods get called, and the child update code will get called as well.
I've got a class that I want make sure the Complete method complete gets called ...somehow. For example:
public class Order
{
public Guid TransactionId {get; private set;}
public void Complete(Guid transactionId)
{
TransactionId = transactionId;
}
}
How can i ensure that the Complete method gets called by clients?
public class Cart
{
public void Process()
{
Order o = new Order();
// Do stuff
o.Complete(GetTransactionId());
}
}
The above code seems weak in that its feasible that the complete methods does not get called:
public class Cart
{
public void Process()
{
Order o = new Order();
// Do stuff
}
}
Heard about events but not too sure if that is the correct solution...Any ideas?
You could make it implement IDisposable and always create a new order within a using statement. That way you can control when the Complete method gets called.
The only way that would not get called is if there was an exception or some other behavior that caused it not to progress to the next statement (ie, catastrophic failure).
You can guard against an exception preventing it from happening by putting it in a finally block:
public void Process()
{
try {
Order o = new Order();
// Do stuff
} finally {
o.Complete(GetTransactionId());
}
}
You want to force the user of an Order to remember to complete it, is that it? If it is the user's choice when to call Complete() then that's gonna be hard. I guess that you either want the complete to be automatically done after something else that is done with the order or you have to somehow make sure that it will be obvious to the user that he forgot to complete it.
It is hard to know without more details of what an order is and how it is used.
I have requirement in which, I have to call some initializing method before the call of any static method in the class.
Now the problem is that whenever i add new static method to that class, I forget to call that initializing method, I was wondering if there any design pattern to solve this problem. I want the initializing method is always called whenever a static method is called from the class.
AOP might be an overkill for this problem. What you may want to try is to delegate each of the static methods to another class and add the initialization code to the constructor of that class. Something like:
class StaticClass {
public static void m1 () {
new Worker().m1();
}
public static void m2 () {
new Worker().m2();
}
}
class Worker {
public Worker() {
intialize();
}
public void m1() {
// Real m1 work
}
public void m2() {
// Real m2 work
}
}
This atleast solves the problem of forgetting to put in the call to init code.
That said, this looks like: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
Can you step back and tell us why you need this?
Something like Spring AOP addresses this situation pretty well for Java. It uses AspectJ annotations to make things a little simpler, although personally I think AOP is fairly complex.
Java has static initialization blocks. Something like this:
public class SomeClass {
static {
// Your code here
}
}
i've some difficult to explain my problem, because i'm also not good in english :|!
I've the following code
namespace StighyGames.MyGames {
public class MyGames
{
...
...
CarClass myCar = new CarClass(...);
Main () {
MyGames game = MyGames(...);
}
}
Game is my "main" object (my application).
In my CarClass i've some code ...
Now, inside myCar (object) i would like to call a function (a method) contained the main class MyGames.. the method "GameOver" .
This, because, if my car "explode" i've to call the GameOver Method.
But GameOver method can't be "child" of myCar ... because GameOver is a method of the game...
Ok.. hope to be explained, my question is: "I don't know how to call a method of the main object class"..
Thank you for your help !
You have several options.
1) Create an event in CarClass and capture it in MyGames.
2) Use a delegate and pass the function reference to CarClass object
3) Add a property to CarClass of type MyGames (say called "Owner"), and after you create CarClass, assign "this" to it: myCar.Owner=this. So you've created a reference in the CarClass object to its creator, and code in CarClass can directly access the methods of its owner.
Which is the best depends on the situation and how these objects will be used. An event is probably preferred, since it offers the most flexibility. A delegate is less flexible and more efficient than an event, though they really serve slightly different purposes. (An event is really an extension of a delegate). The last one is probably the worst form, generally, since it tightly binds the objects, but it has a time and place.
Here's #1
public class CarClass
{
// A delegate is a pointer to a function. Events are really a way of late
// binding delegates, so you need to one of these first to have an event.
public delegate void ExplodedHandler(CarClass sender);
// an event is a construct which is used to pass a delegate to another object
// You create an event based for a delegate, and capture it by
// assigning the function reference to it after the object is created.
public event ExplodedHandler Exploded;
protected void CarCrash()
{
... do local stuff
// Make sure ref exists before calling; if its required that something
// outside this object always happen as a result of the crash then
// handle the other case too (throw an error, e.g.)/
// See comments below for explanation of the need to copy the event ref
// before testing against null
ExplodedHandler tempEvent = Exploded;
if (tempEvent != null) {
tempEvent(this);
}
}
}
public class MyGames
{
...
...
CarClass myCar = new CarClass(...);
myCar.Exploded += new ExplodedHandler(GameOver);
Main () {
MyGames game = MyGames(...);
}
void GameOver(CarClass sender) {
// Do stuff
}
}
As everyone has answered you have several options. But not all the options are equally good.
Here my list.
1) Add an event to the Car object and let the Game register to it.
2) Pass a delegate to the Car object
3) Pass to the Car object a reference to a Game
4) Use static call.
All the answer except the first are "bad" ;)
Here the code. I'm using C# 4.0
public class Car
{
public event Action<Car> Explode;
private void OnExplode()
{
Explode(this);
}
}
public class Game
{
private Car car;
public Game()
{
car = new Car();
car.Explode += new Action<Car>(NotifyExplosion);
}
private void NotifyExplosion(Car car)
{
Console.WriteLine("{0} is exploded", car.ToString());
GameOver();
}
private void GameOver()
{
Console.WriteLine("GAME OVER");
}
static void Main(string[] args)
{
Game game = new Game();
}
}
You can use the Singleton design pattern on your main class.
Or you can revert the problem, and implement a CheckGameOver in MyGames, that would poll the car for its state. That would be my preferred method, as it reduces dependencies.
You can pass a reference to your MyGames instance into your CarClass instance, it's the 'parent' reference. While I would think that you might better architect your game using events and delegates, there's nothing to stop you calling a method on the parent object.
You could:
Modify your CarClass class (which really should be renamed Car) to hold a reference to the Game it belongs to.
Create an Event on the Car class called Explode. The Game class could then register for the Explode event and make sure the GameOver() method gets called from that handler.