0

Could you explain to me. How i have to resolve simple task below?

class Base{}
class Derived1: Base { void Method(); }
class Derived2: Base { void Method();}

static void Main(string[] args)
{   
    Base object; //it is just a declaring

    if (some condition is true)
        object = new Derived1();
    else
        object = new Derived2();

    //now i want to call one of methods of one of my derived classes
    //object.MyMethod(); //of course wrong, object has no that method

    //ok, i have to downcast it but i don't know which class to
    //((object.GetType())object).Method(); //wrong

    //is there only one way is to repeat conditions 
    //and to downcast explicitly?

    if (some condition is true again)
        (object as Derived1).Method();
    else
        (object as Derived2).Method();
}

Base class is know nothing about Method() of course.

Roman Wood
  • 23
  • 3
  • If there's a reason to derive from a base type, i.e. Derived1 and Derived2 are related, then either abstract or virtualize your method on the base class; then you won't need to cast. At the moment it's like you're trying to say `if(x) then buy milk else tell the dog to bark`. – Matthew Layton Feb 16 '17 at 14:03

5 Answers5

2

I suggest using abstract method in the Base class overriden in both derived ones:

abstract class Base { public abstract void Method();}
class Derived1: Base { public override void Method(); }
class Derived2: Base { public override void Method(); }

Then

static void Main(string[] args) {   
  Base instance; 

  if (some condition is true)
    instance = new Derived1();
  else
    instance = new Derived2();

  instance.Method();
}

Implementing interface is an alternative:

interface IBase {void Method();}

class Derived1: IBase { void Method(); }
class Derived2: IBase { void Method(); }

static void Main(string[] args) {   
  IBase instance; 

  if (some condition is true)
    instance = new Derived1();
  else
    instance = new Derived2();

  instance.Method();
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

Use an interface if the class is there just for declaration & does not have any concrete methods :

interface Base{
void Method();
}

class Derived1: Base { void Method(){} }
class Derived2: Base { void Method(){}}

    static void Main(string[] args)
{   
    Base obj; //it is just a declaring

    if (some condition is true)
        obj = new Derived1();
    else
        obj = new Derived2();

 //Call it directly
        obj.Method();    
}
Abdul Rehman Sayed
  • 6,532
  • 7
  • 45
  • 74
0

What you need to understand is what inheritance and polymorphism are for.

Inheritance

Allows related objects to derive from a common ancestor.

abstract class Shape
{
}

sealed class Rectangle : Shape
{
}

sealed class Circle : Shape
{
}

Polymorphism

Allows derived types to have different implementations to perform a common behavior.

abstract class Shape
{
    abstract double GetArea();
}

sealed class Rectangle : Shape
{
    override double GetArea() // same behaviour
    {
        return x * y; // different implementation
    }
}

sealed class Circle : Shape
{
    override double GetArea() // same behavior
    {
        return PI * r * r; // different implementation
    }
}

Interfaces vs. Abstract Classes

Interfaces define what an object can do. In the example below, Dog and Cat implement the IAudible interface which exposes a MakeNoise method. Note, IAudible is not what the object is, it's what it can do.

class Dog : IAudible
{
    public void MakeNoise()
    {
        Console.WriteLine("Woof");
    }
}

class Cat : IAudible
{
    public void MakeNoise()
    {
        Console.WriteLine("Meow")
    }
}

IAudible d = new Dog();
d.MakeNoise(); // Woof

IAudible c = new Cat();
c.MakeNoise(); // Meow

Abstract classes define what an object is. In the example below, Dog and Cat extend Animal, because Dogs and Cats are Animals.

abstract class Animal
{
    public string Noise { get; protected set; }
}

sealed class Dog : Animal
{
    public Dog()
    {
        Noise = "Woof";
    }
}

sealed class Cat : Animal
{
    public Cat()
    {
        Noise = "Meow";
    }
}

Animal d = new Dog();
d.Noise; // Woof;

Animal c = new Cat();
c.Noise; // Meow

To answer your question, decide how and why your objects are related. If they are related by what they can do, then use an interface. If they are related by what they are, then use an abstract class.

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
0

Agree with each answer. Thanks all.

But there is one else ..crutch.. by using delegate

class Base
{
    public delegate string Method();
    public Method m;
}
class Derived1 : Base
{
    public string ParticularMethod()
    {
        return "Particular method of derived 1";
    }
}
class Derived2 : Base
{
    public string ParticularMethod()
    {
        return "Particular method of derived 2";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Base obj; //it is just a declaring

        if (true)
        {
            obj = new Derived1();
            obj.m = (obj as Derived1).ParticularMethod;
        }
        else
        {
            obj = new Derived2();
            obj.m = (obj as Derived2).ParticularMethod;
        }

        Console.WriteLine(obj.m());
        //"Particular method of derived 1"
        Console.ReadKey();

    }
}
Roman Wood
  • 23
  • 3
0

OR so

dynamic obj; //it is just a declaring

if (true)
    obj = new Derived1();
else
    obj = new Derived2();

Console.WriteLine(obj.ParticularMethod());
//"Particular method of derived 1"
Console.ReadKey();

It works too

Roman Wood
  • 23
  • 3