William Thomas
William Thomas

Reputation: 2126

Returning in a base class's method returns in child class call?

I'm creating a C# framework in which (nearly) all of my classes will be based off of a single, abstract base class. This base class contains some privately-set properties, one of which being the boolean Garbage.

In XNA's draw loop, I don't want any child classes to execute the code in their respective Draw() methods if the base class's Garbage property is set to true. I tried doing this with the following implementation:

Abstract base class:

public virtual void Draw(GameTime GameTime, SpriteBatch SpriteBatch)
{
    if (Garbage) return;
}

Inherited class:

public void Draw(GameTime GameTime, SpriteBatch SpriteBatch, Color OverlayColor, float Scale)
{
    base.Draw(GameTime, SpriteBatch);

    //Other code here...
}    

Because the base class's Draw method is being called before the actual code in my child class, it hits that return statement, which I would want to follow through into my child class's Draw() call. However, this isn't happening.

Is there any way to achieve the effect I want, without adding that "if (Garbage) return;" restriction to the top of every inherited class's Draw() method?

Upvotes: 3

Views: 2711

Answers (6)

MyKuLLSKI
MyKuLLSKI

Reputation: 5325

I think your doing things a little backwards. Your least overloaded method should call the call the next least and so on.

Example of my draw method

public override void Draw(List<string> menuOptions, int currentSelection, MenuType type)
{
    Draw("", menuOptions, currentSelection, type, Color.White, Color.Gray, Color.WhiteSmoke, Color.DimGray);
}

public void Draw(string menuName, List<string> menuOptions, int currentSelection, MenuType type)
{
    Draw(menuName, menuOptions, currentSelection, type, Color.White, Color.Gray, Color.WhiteSmoke, Color.DimGray);
}

public void Draw(string menuName, List<string> menuOptions, int currentSelection, MenuType type, Color foreNorm, Color backNorm, Color foreSelect, Color backSelect)
{
    //Actual Draw
}

Upvotes: 1

Austin Salonen
Austin Salonen

Reputation: 50225

If at all possible, you might want to consider the Template Method Pattern. Have the primary method be this:

public void Draw(GameTime gameTime, SpriteBatch spriteBatch, Color overlayColor, float scale)
{
    if (Garbage) return;

    DrawMe(gameTime, spriteBatch, overlayColor, scale);
}

protected abstract DrawMe(GameTime gameTime, spriteBatch SpriteBatch, Color overlayColor, float scale);

With each child class implementing the required DrawMe method (admittedly a poor name), you get the flow you want and the specific classes only knowing how to draw themselves.

Upvotes: 4

Tigran
Tigran

Reputation: 62256

Well, just an example:

public class BaseClass 
{
   public bool Garbage {get;set}
}

//somewhere you have a collection of all artifacts to draw (children of BaseClass) 
Lis<BaseClass> stuffToDraw = new List<BaseClass){....}

//and somewhere in the framewrok you have a method to draw them  

public void Paint(...)
{
     stuffToDraw.ForEach(stuff=>
     {
         if(stuff.Garbage) return; 
         stuff.Draw(....); //call of overriden virtual method
     });
}

In this way you have one place where to check if to draw an artifact or not.

Hope this helps.

Upvotes: 1

OnResolve
OnResolve

Reputation: 4032

No there's no way through inheritance / polymorphism to achieve what you want. What I would suggest is having an Entity Manager that contains all your objects looking to draw, and can foreach through each saying something to the effect of:

foreach (IEntity entity in _entities)
{
       if(!entity.Garbage)
            entity.Draw(....);
}

This way if draw is called, the object can do what it's supposed to and the is garbage is moved to a different level and allows it to be flexible so if later you need another clause added before an object can draw, you only need to change 1 line of code, rather than each draw method and basically get the effect you were initially striving for.

Upvotes: 4

Erik Dietrich
Erik Dietrich

Reputation: 6090

One thing that you might consider is to have two methods. You could have your Draw method on the abstract base, which is not overridden, and then define an abstract protected method called PerformDraw() that your inheritors override.

Abstract base draw looks like:

public void Draw(GameTime GameTime, SpriteBatch SpriteBatch)
{
    if (!Garbage) PerformDraw(GameTime, SpriteBatch);
}

This lets you override the draw behavior but forces all inheritors to use the "garbage" check.

Upvotes: 5

Tejs
Tejs

Reputation: 41246

If you want your child class to bail on the function call based on some situation in the parent class on a void return call, your have the following choices:

1) Check a protected / public flag variable in your child method and then branch logic. AKA

// base class
if (Garbage) _someFlag = true;

// child class

base.Draw();

if(!_someFlag) // Do Stuff

2) Throw an exception in your parent class, which stops the rest of the function from executing (assuming this is appropriate to your situation).

In your particular case, you're trying to return data from the parent class to the child class through a void method. If this was me, I would do something like this:

// base class
public bool IsGarbage { get; set; }

// child class

public void Draw()
{
     if(!IsGarbage)
     {
         // Do Stuff
     }
}

Upvotes: 1

Related Questions