How to call a common function in a class instance? [duplicate] - c#

This question already has answers here:
Return one of two possible objects of different types sharing a method
(6 answers)
Closed 8 years ago.
Let's say i have two classes:
class Batman
{
public void Robin(){...}
public void Jump(){...}
}
class Superman
{
public void Kryptonie(){...}
public void Jump(){...}
}
Now, I have an instance of those classes:
public object Crossover()
{
var batman = new Batman();
var superman = new Superman();
return superman;
}
I do not know instance of which class the Crossover will return, it could be Batman or Superman.
var someVariableName = Crossover(); //I don't know if this contains an instance of Superman or Batman;
//I do know that no matter which class instance is returned, it will always contain a function named Jump which i want to trigger:
someVariableName.Jump();
Now i know i could do something like:
if (someVariableName.GetType() == typeof(Superman))
{
((Superman) someVariableName).Jump()
}
But is there a way to trigger the Jump function without having to manually check for each type with if..else.., when i know that the instance of the class saved in that variable will always contain a Jump function?

Use an interface:
interface ISuperHero
{
void Jump();
}
class Batman : ISuperHero
{
public void Robin(){...}
public void Jump(){...}
}
class Superman : ISuperHero
{
public void Kryptonie(){...}
public void Jump(){...}
}
Then return the interface from your method:
public ISuperHero Crossover()

This is where interfaces become useful. Consider this interface:
public interface ISuperhero
{
void Jump();
}
And these implementations:
class Batman : ISuperhero
{
public void Robin(){...}
public void Jump(){...}
}
class Superman : ISuperhero
{
public void Kryptonie(){...}
public void Jump(){...}
}
They're individual implementations, but they share a common polymorphic interface. Your function can then return that interface:
public ISuperhero Crossover()
{
var batman = new Batman();
var superman = new Superman();
return superman;
}
Since that interface has a Jump() method, it can be called directly:
var someVariableName = Crossover();
someVariableName.Jump();

You could create a base class defining the method (or an interface, if it is just about the method definition). You can override the implementation in the deriving classes then.
abstract class ActionFigure
{
public abstract void Jump(); // just define it has a Jump method, but implement it in the deriving class
public void SomethingGeneral()
{
// no need for an override, just implement it here
}
}
class Batman : ActionFigure
{
public void Robin(){...}
public override void Jump(){...}
}
class Superman : ActionFigure
{
public void Kryptonie(){...}
public override void Jump(){...}
}

Related

Dependency injection with abstract class in .NET Core

I don't know how to use a dependency injection in an abstract class. Let me show you my problem in a simple example:
public abstract class Animal {
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000); //how to get this service here?
}
}
public class Cat : Animal
{
public readonly IMotionService _motionService;
public Cat(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
public class Bird : Animal
{
public readonly IMotionService _motionService;
public Bird(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Fly();
}
}
Every animal move in different way so the Move() function is implemented separately in every derived class. As you probably noticed the whole implementation comes from the motionService.
On the other hand all animals sleep in same way, so I want put the Sleep() implementation in a base abstract class to avoid a duplication code, but I can't use my restService with a Sleep implementation because I don't have idea how to inject a service class into an abstract class.
I thought about IServiceProvider but it should be injected too.
You pass it down like this:
public abstract class Animal
{
private readonly IRestService restService;
public Animal( IRestService restService )
{
this.restService = restService;
}
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000);
}
}
public class Cat : Animal
{
// vv Should be private!
public readonly IMotionService _motionService;
public Cat(IMotionService motionService,
IRestService restService)
: base(restService) // pass on to base class ctor
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
// Same in `Bird` class
For reference: Using Constructors (C# Programming Guide)

How to abstract/remove redundent methods in the following class sample

I'm trying to remove the redundancy I have in my Enemy0, Enemy1, ... classes that inherit from my abstract Enemy class. This is all Monogame/XNA.
My abstract class looks like so:
public abstract class Enemy
{
public abstract Vector2 Position { get; }
public Enemy() {}
public abstract void Update(GameTime gameTime);
public abstract void Draw(SpriteBatch spriteBatch);
public abstract Part getLeftPart();
public abstract Part getRightPart();
public abstract Part getLeftLeftPart(); //This method only used in Boss0 classes
public abstract Part getRightRightPart(); //This method only used in Boss0 classes
}
Though my Enemy# classes vary in implementation, some methods are exactly the same/redundant and take up room (but have parameters relative to that class, eg the private variable _leftPartPos).
The problem occurs when I have 20 or so Enemy# classes and I decide to add an extra parameter to the Part object (which is used in getLeftPart()- I would have to also modify 20 of those classes that inherit the Enemy
public class Enemy0 : Enemy
{
private Texture2D _partTexture;
private Vector2 _leftpartPos;
private Vector2 _rightPartPos;
public override Vector2 Position
{
get { return _position; } // Reason for this get is to access inner variables
} // like _position.X = 10
private Vector2 _position;
public Enemy() {}
public abstract void Update(GameTime gameTime)
{
// Some varying functionality per inheriting class
}
public abstract void Draw(SpriteBatch spriteBatch)
{
// Some varying functionality per inheriting class
}
public override Part getLeftPart() // This always returns the same object (with
{ // different params)
return new Part(
_partTexture,
_leftPartPos,
SpriteEffects.FlipHorizontally);
}
public abstract Part getRightPart()
{
return new Part(
_partTexture,
_rightPartPos,
SpriteEffects.None);
}
public override Part getLeftLeftPart()
{
return null; // This only returns an instance in Boss0, Boss1, etc
}
public override Part getRightRightPart()
{
return null;
}
}
The reason I have this abstract class is so that I can initialize a List<Enemy> object and access its varied methods without having to cast each class as Enemy0, Enemy1, ...
Is there a way I can throw in the functionality of getLeftPart(), getRightPart(), ... into my abstract class? Is there a better approach for all this?
Declare them as virtual instead of abstract. That way you can provide a base implementation in the root class and override it in the child classes if they require different functionality.
public abstract class RootClass
{
public virtual void DoSomething()
{
Console.WriteLine("I'm doing something in the root class");
}
}
public class ChildClass1 : RootClass
{
public void SomethingElse()
{
DoSomething(); //Prints out "I'm doing something in the root class"
}
}
public class ChildClass2 : RootClass
{
public void SomethingElse()
{
DoSomething(); //Prints out "I'm doing something in ChildClass2
}
public override void DoSomething()
{
Console.WriteLine("I'm doing something in ChildClass2");
}
}
If you have to take variable numbers of parameters, declare the method with the params attribute, like:
public virtual void DoSomething(params object[] args)
This causes boxing, so be aware of the performance implications. If you need to do something more specific, try:
public virtual void DoSomething<T>(params T[] args)
But the only difference here is that all the parameters must be of the same type, or convertible to that type. If you only need one parameter of some type, use:
public virtual void DoSomething<T>(T arg)
or you can have two (or more types)
public virtual void DoSomething<T1, T2>(T1 arg1, T2 arg2)
etc, etc.

calling every class that inherits a base class without knowing the class exists c#

I'm trying to implement a system in a websocket server similar to what unity3d does. they have a base class called MonoBehavior that all classes inherit from.
these class have certain functions (start, ongui, update) that get called at certain intervals.
every class that inherits from that class has its functions called (update is called every frame)
I want to make a base class and then call that and have every class that contains one of the functions automatically called like unity3d does. I've tried googling but have no idea what this type of behavior with classes is called to even get a useful result
Why not just implement a static Manager class, like below:
public static class CallManager
{
public static HashSet<Callable> callables = new HashSet<Callable>();
// Other management code...
}
With a base class, that all your callable classes subclass, that automatically adds the each new instance to Set of callable objects managed by your CallManager:
public abstract class Callable
{
public Callable()
{
OnCreate();
}
protected void OnCreate()
{
CallManager.callables.Add(this);
}
public abstract void Start();
public abstract void OnGUI();
public abstract void Update();
}
Now, whenever someone creates a new Callable, the base Callable constructor will update the CallManager with the new Callable. A full example program is below:
class Caller
{
public static void Main(string[] args)
{
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
foreach (Callable c in CallManager.callables)
{
c.Start();
c.OnGUI();
c.Update();
}
}
}
public abstract class Callable
{
public Callable()
{
OnCreate();
}
protected void OnCreate()
{
CallManager.callables.Add(this);
}
public abstract void Start();
public abstract void OnGUI();
public abstract void Update();
}
public static class CallManager
{
public static HashSet<Callable> callables = new HashSet<Callable>();
}
public class Callee1 : Callable
{
public Callee1()
{
}
public override void Start()
{
Console.WriteLine("Callee1::Start");
}
public override void OnGUI()
{
Console.WriteLine("Callee1::OnGUI");
}
public override void Update()
{
Console.WriteLine("Callee1::Update");
}
}
public class Callee2 : Callable
{
public Callee2()
{
}
public override void Start()
{
Console.WriteLine("Callee2::Start");
}
public override void OnGUI()
{
Console.WriteLine("Callee2::OnGUI");
}
public override void Update()
{
Console.WriteLine("Callee2::Update");
}
}
Maybe something like this:
public static class Caller {
public static event EventHandler Updating;
public static Update() {
var handler = Updating;
if (handler ยก= null) handler(null, EventArgs.Empty);
}
}
public abstract class Base {
protected Base() {
Caller.Updating += Caller_Updating;
}
void Caller_Updating(object sender, EventArgs e) {
Update();
}
protected abstract Update();
}
For what i understand, you want that all derived class have the method called. This way when you call Caller.Update all derived class of Base have they Update method executed.
I believe you're referring to the Template Method design pattern, also commonly known as hooks. It's the building block of many, many frameworks. It works something like this:
public abstract class BaseClass
{
public void Start()
{
//execute start logic
DoThis();
DoThat();
//call base class's hook
OnStart();
}
protected abstract void OnStart();
}
You declare an abstract method OnStart that derived classes must implement. When the base class's Start method is called, the base class invokes the hook which is then executed by the derived class.
If you want to make overriding the hook optional, then you declare the method virtual with an empty implementation, i.e. protected virtual void OnStart() { }.
It might be also worth mentioning that this is at the core of the Hollywood Principle: "Don't call us, we'll call you!" (i.e., you don't call the framework's classes - the framework will call you!)

Template method pattern without inheritance

How can a variant of the Template Method pattern be implemented whereby the concrete class does not inherit from the base class, but the overall feature of the pattern is maintained. The reason it cannot inherit is that it's forced to inherit from another class and multiple-inheritance is unavailable.
For example, suppose the following Tempate Method pattern:
public abstract class BaseClass {
public void Alpha() {
Beta();
}
public abstract void Beta();
public void Gamma() {
Delta();
}
public abstract void Delta();
}
public ConcreteClass : BaseClass {
public override void Beta() {
Gamma();
}
public override void Delta() {
Console.WriteLine("Delta");
}
}
...
var object = new ConcreteClass();
object.Alpha(); // will outout "Delta"
How can I achieve the same result without ConcreteClass inheriting BaseClass?
Your base class could depend on an interface (or other type) that's injected via the constructor. Your template method(s) could then use the methods on this interface/type to achieve the pattern's desired outcome:
public class BaseClass
{
IDependent _dependent;
public BaseClass(IDependent dependent)
{
_dependent = dependent;
}
public void Alpha() {
_depdendent.Beta();
}
public void Gamma() {
_depdendent.Delta();
}
}
Effectively using composition rather than inheritance.
You can achieve this by providing a reference to the base class on method call:
public ConcreteClass {
public void Beta(BaseClass baseClass) {
baseClass.Gamma();
}
public void Delta() {
Console.WriteLine("Delta");
}
}

Restricting subclasses from inheriting certain methods of base class

using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}

Categories

Resources