Handling Specified Member Classes In C# - c#

In building a class structure, I would like to have derived classes potentially posses derived member classes. For example:
class GamePiece
{
}
class Checker : GamePiece
{}
class ChessMan : GamePiece
{}
class Game
{
protected GamePiece _piece;
}
class Checkers : Game
{
Checkers(){ _piece = new Checker(); }
}
class Chess : Game
{
Chess(){_piece = new ChessMan();}
}
This is seriously oversimplified, but makes the actual point. Now assuming that there are events and such, I would like to attach the common ones in the base class constructor, and the specialized ones in the derived constructor. For example both a checker and a chessman might have a "captured" event and a "moved" event. I would like to attach them in the base constructor. However, events that would be specific such as "castled" or something like that would be attached only in the specific constructor.
The problem I have is that the base constructor seems to only be able to run BEFORE the derived constructor. How do I effect this such that I get to actually instantiate the "gamepiece" before I call the base "Game" constructor to attach to events.
My gut suggests that this is better handled by removing that functionality from the constructor and simply having an "Attach()" member function and handling it there. However, I want to make sure I am going in the right direction, since it would seem there should be a way to do it in the constructor.

You can try injecting it from child to parent, like this:
abstract class Game {
protected GamePiece _piece;
protected Game(GamePiece piece)
{
_piece = piece;
// do the common work with pieces here
}
}
class Checkers : Game
{
public Checkers(Checker piece) : base(piece)
{
// piece-specific work here
}
}
If you need more complicated work done than just instantiating, you could create a static factory method that did all the work, and just call that when invoking the base constructor. This does change your Game implementation slightly in ways that change how you instantiate it, but that can be solved by using a factory object anywhere you need a new Game.
Edit: I actually realized the original code-sample I posted wasn't correct; there was no way to reference the Checker piece (as a Checker) in the Checkers class. But if you inject the Checker piece into that as well, the problem is solved and you have your reference. This is dependency injection, by the way.

You could try the Template design pattern:
class Game
{
Game() { Init(); }
protected virtual void Init() {}
}
Now you can insert generic event handling in the Game Init method and override it with concrete handling logic in the descendants.

Related

Finding and starting a generic class?

I have a Unity C# application where every game inside has one abstract controller. It inherits from another class enabling it to be accessed like a static version of the base behavior in unity.
public class AbstractController<T> : SingletonMonoBehavior<T> {
virtual public void Begin() {
//startup code here
}
}
So, to find this class, I have to know what T will be. Do I need reflection for this? Or can I just store T types in a List somewhere, and access them dynamically? Right now, I DO have a dictionary of game names and classes that inherit from abstract controllers -- so I know what T is supposed to be, but when I do this:
_controllerTypes = new Dictionary<GameScene, Type> ();
_controllerTypes.Add (GameScene.FrogJump, typeof(FJGameController));
Type T = _controllerTypes [_startScene];
AbstractController<T>[] controllers = GameObject.FindObjectsOfType<AbstractController<T>> ();
I get a compiler error stating that "The type or namespace name `T' could not be found." Is there a way to design around this? I don't want to use reflection, but I want it to be pretty.
What you are about to do is absolutely possible but requires the use of reflection. You shouldn't do this as it will affect the performance of your game. Like Catlard mentioned in the comment section, use interface.
interfaces allow you to guarantee that a class has a function, but how
do you access that class in the first place? You can't just
GetComponent for all IControllable interfaces, for example. I'd still
have to have an abstract controller class, right?
You can use GetComponent to check for an interface.
public class Player : MonoBehaviour, IControllable
{
}
then your Interface:
public interface IControllable
{
}
Now, lets say that your Player script is attached to a GameObject called "Player".
GameObject plyrObj = GameObject.Find("Player");
if (plyrObj.GetComponent<IControllable>() != null)
{
Debug.Log("Player is Controllable");
}
Your can also have multiple interface for different classes. You can also make the interface generic with something like public interface IControllable<T>{}. This should help you re-do your work.

Hook to object instantiation

I'm wondering if there's a way to hook to an event whenever an object is instantiated.
If it doesn't, is there a way to retrieve the object to which an attribute is attached to when the attribute is instantiated?
What I want to do is give some of my classes a custom attribute and whenever a class with this attribute is instantiated, run some code for it.
Of course, I could simply place the code in each of those classes' constructor but that's a lot of copy and pasting and I could easily forget to copy that code into one or two classes. And of course, would be very convenient for end users as all they would have to do is add my attribute to their classes and not worry about remember to add that bit of code in their constructors.
I actually can't do a base class because all of those objects already have a base.
Thanks in advance.
Here's an example of what I'd like to do. Either use the attribute's constructor or have an event handler for object instantiation.
public class MySuperAttribute : Attribute
{
public MySuperAttribute()
{
//Something akin to this or the event in Global
Global.AddToList(this.TheTargetObject);
}
}
[MySuperAttribute]
public class MyLabel : System.Windows.Forms.Label
{
}
public static class Global
{
public static void AddToList(Object obj)
{
//Add the object to a list
}
//Some pseudo-hook into the instantiation of any object from the assembly
private void Assembly_ObjectInstantiated(Object obj)
{
if(obj.GetType().GetCustomAttributes(typeof(MySuperAttribute), true).Count != 0)
AddtoList(obj);
}
}
There is no easy way to hook object instantiation externally, maybe with some debugging API, and it has a good reason. It makes your code harder to maintain and understand for other people.
Attributes won't work, because the instance of an attribute is not actually created until it is required - via reflection, and an attribute is assigned to a type, not an instance.
But you may well put the code in a base class, and derive all other classes from it, although it is also not a good practice to pass half-initialized instance to other methods. If the class inherits from ContextBoundObject, you can assign a custom implementation of ProxyAttribute to it and override all operations on it.
If you can't create a common base class (when your types inherit from different types), you can always create the instance with a custom method like this one:
public static T Create<T>() where T : new()
{
var inst = new T();
Global.AddToList(inst);
return inst;
}
However, seeing as you inherit from form controls, their instantiation is probably controlled by the designer. I am afraid there is no perfect solution, in this case.

C#, Unity - Single function taking multiple different objects

I am in need of your help.
I am in the middle of arranging a script that can check various conditions before an ability can be executed in a RPG game.
All these abilities are in individual classes (Fireball, Heal, Poison) all derived from another abstract class (Ranged ability, Healing ability, DOT ability), which all are parented to an abstract class (Ability).
In order to avoid creating multiple functions, to handle every single ability:
void condition(Fireball f){//test};
void condition(Heal f){//test};
void condition(Poison f){//test};
I am trying to create a single function call that can take all types of abilities.
void condition(Ability f){//test}
So far I have succeded in creating a Fireball object and pass it to the function.
Fireball _fire = new FireBall();
condition(_fire);
void condition(Ability f){//test}
From here I can access all the public variables initialized in the Ability class, but I can't access the public variables initialized in the derived classes (Ranged ability, Healing ability, DOT ability).
Is it me who is forgetting something, or am I looking at this at a wrong perspective? (I am not great at utilizing inheritance and abstract classes.)
Without knowing more details of what the condition function does, you have two options.
One, you can do something like
if (f.GetType() == typeof(FireBall))
{
fireBall = (FireBall)f;
fireBall.FireTheFireBall();
}
else if (f.GetType() == typeof(Heal))
...
Or, your Ability can have an abstract Activate method, which all derived classes are required to overload:
class Fireball
{
public override void Activate()
{
//do fireball specific things
this.FireTheFireBall();
}
public void FireTheFireBall() {...}
}
class Heal
{
public override void Activate()
{
//do healing specific things
this.ApplyTheBandage();
}
...
}
abstract class Ability
{
public abstract void Activate();
}
void condition(Ability f){
f.Activate(); //runs the version of Activate of the derived class
}
Then any thing that works with an Ability can call someAbility.Activate() and the implementation provided by the derived class will get executed.
You should also study up on interfaces, which are kind of like abstract classes. The benefit of interfaces is you can implement multiple of them, whereas you are limited to inheriting from only one base abstract class. Think about a IKnob interface that has Turn and Pull functions. You might have a Drawer class that implements IKnob, a Door class, a TrappedDoor class which implements Turn and activates a trap. A Player walks up to a door, and hits the Use button on it, and you pass to the open function the object, Open(IKnob knob)
void Open(IKnob knob)
{
knob.Turn();
knob.Pull();
}
class TrappedDoor:IKnob,IMaterial,ISomethingElse,IHaveTheseOtherCapabilitiesAsWell
{
private bool TrapAlreadySprung{get;set;}
//more complex properties would allow traps to be attached either to the knob, or the door, such that in one case turning the knob activates the trap, and in the other, Pull activates the trap
public Turn() {
if(! TrapAlreadySprung)
{
MessageBox("You hit your head, now you're dead");
}
}
}
There's ways to check if something has an interface, so if some a player walks up to an item and tries to talk to it you can check if the object has the ICanTalk interface, if it does then call object.GetReply("Hello") and the object can respond. So you can have talking doors and rocks if you so desire. You get all your code that handles talking to things/displaying responses etc. working with ICanTalk interface methods, and then other classes can implement ICanTalk and they each decide how they respond to be talked to. This concept is known as "seperation of concerns" and helps you create more reusable code.
The important thing is you can write a piece of code, an algorithm, function, etc, that only works with that interface, and that way once you get that code working with the interface, you can then use that interface on any class, and that class can leverage the prexisting code.
I.e. your condition function, if it took in an IAbility interface, once you have that code working, then any class you create that implements IAbility can be passed to the condition function. The condition function is in charge of doing whatever it's supposed to, and the class implementing IAbility takes care of whatever is specific to it inside of the methods it implemented.
Of course the classes implementing the abstract class or interface must implement the methods required, so sometimes you might feel like you are duplicating code. For example, if you have similar classes, like TrappedDoor and Door, a TrappedDoor might behave just like a regular Door if the trap is not set/already sprung. So you might either inherit from Door in this case, or have a private Door property(known as "composition"). If the trap is already sprung, then you can call into the base Door class or private Door property and call .Turn so that you just reuse the default behavior of a regular door in the case that the trap isn't active.
Test if object implements interface
Personally I mostly use interfaces and composition, instead of inheritance. Not that inheritance it terrible, but inheritance hierarchies can quickly become very complicated.

OOD, inheritance, and Layer Supertype

I have a question concerning holding common code in a base class and having the derived class call it, even though the derived class's trigger method has been dispatched from the base. So, base->derived->base type call stack.
Is the following look OK, or does it smell? I have numbered the flow steps...
public abstract class LayerSuperType
{
public void DoSomething() // 1) Initial call from client
{
ImplementThis(); // 2) Polymorphic dispatch
}
protected abstract void ImplementThis();
protected void SomeCommonMethodToSaveOnDuplication(string key) // 4)
{
Configuration config = GetConfiguration(key);
}
}
public class DerivedOne : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("whatever"); // 3) Call method in base
}
}
public class DerivedTwo : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("something else"); // 3) Call method in base
}
}
That looks absolutely fine. Perfect example of why you'd use an abstract class over an interface. It's a bit like a strategy pattern and I have used this fairly regularly and successfully.
Make sure that what the class doing is still dealing with one 'concern' though, only doing one task. If your base class does repository access but the objects are representing documents, don't put the functionality in the base class, use a separate repository pattern/object.
Looks like a very simplified Template Method Pattern where your sub-classes do some specific kinds of things at the right points in the implementation of your algorithm, but the overall flow is directed by a method on the base class. You've also provided some services to your sub-classes in the form of base class methods; that's ok too as long as you're good as far as SOLID goes.
Why not public abstract void DoSomething() and forget about ImplementThis() altogether?
The only reason I can see to leave ImplementThis() is if you want to maintain a consistent interface with DoSomething() which later on down the road will allow the signature of ImplementThis() to change without a breaking change to callers.
I agree that you should maintain a single concern with the class's responsibility but from an overall OOP perspective this looks fine to me. I've done similar on many occasions.
It does smell a little that SomeCommonMethodToSaveOnDuplication is being called in two different ways. It seems to be doing two unrelated things. Why not have two methods?

Can you force a method to be called inside a class constructor, else throw compile error?

I have a class, Player, which inherits from AnimatedSprite. AnimatedSprite has a protected abstract method, loadAnimations, which Player must override to load the actual animations (since animations will vary based on the sprite image, it needs to be implemented by the class deriving from AnimatedSprite).
However, while I force the class user to implement the method, is there a way to force the user to actually call this method, preferably inside the Player constructor, to ensure that the animations are always loaded? I'm pretty sure C# doesn't have any language features to do this (though I could be wrong), so perhaps there's a better class design pattern that I can implement which I'm overseeing?
As always, thanks in advance!
It is actually not recommended to call virtual methods in a constructor, since they may use state that is not yet initialized (the relevant constructor has not yet been called).
Personally I would just had an abstract method that you call after the constructor, maybe via a factory:
static T Create<T>() where T : TheBase, new()
{
T obj = new T();
obj.Init();
return obj;
}
i think that calling methods inside constructor is not a good approach...
i'm used to do this way:
public abstract class AnimatedSprite
{
public void LoadAnimations()
{
OnLoadAnimations();
}
protected abstract void OnLoadAnimations();
protected virtual void OnNextFrame() { };
....
}
I'm assuming AnimatedSprite is an abstract class. Just add the call to the method inisde AnimatedSprite's constructor.

Categories