2017-02-16 15 views
-1

Не могли бы вы объяснить мне. Как мне решить простую задачу ниже?C# Общее неявное ускорение экземпляра по типу

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(); 
} 

Базовый класс ничего не знает о методе(), конечно.

+0

Если есть причина, чтобы извлечь из базового типа, т.е. Derived1 и Derived2 связаны, то либо абстрактные, либо виртуализировать ваш метод в базовом классе; то вам не нужно будет бросать. На данный момент это похоже на то, что вы пытаетесь сказать: «Если (x), то покупайте молоко, еще скажите собаке лаять». – series0ne

ответ

2

я предлагаю использовать абстрактные метод в Base класса перекрываться в обоих полученных из них:

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

Затем

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

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

    instance.Method(); 
} 

Реализация интерфейс является альтернативой:

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(); 
} 
1

Используйте interface если класс существует только для объявления & не имеет каких-либо конкретных методов:

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();  
} 
0

То, что вы должны понять, что наследование и полиморфизм для.

Наследование

Позволяет связанные объекты, чтобы получить от общего предка.

abstract class Shape 
{ 
} 

sealed class Rectangle : Shape 
{ 
} 

sealed class Circle : Shape 
{ 
} 

Полиморфизм

позволяет производным типов имеют различные реализации для выполнения общего поведения.

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 
    } 
} 

Интерфейсы против Абстрактные классы

Интерфейсы определяют , что объект может сделать. В приведенном ниже примере Dog и Cat реализуют интерфейс IAudible, который предоставляет метод MakeNoise. Примечание. IAudible - это не то, что объект, это то, что он может сделать.

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 

абстрактные классы определяют , что объект является. В приведенном ниже примере Dog и Cat продлены Animal, потому что Собаки и кошки - животные.

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 

Чтобы ответить на ваш вопрос, определите, как и почему связаны ваши объекты. Если они связаны тем, что они могут сделать, используйте интерфейс. Если они связаны тем, чем они являются, то используйте абстрактный класс.

+0

Lucidly. благодаря –

0

Согласитесь с каждым ответом. Спасибо всем.

Но есть один еще ..crutch .. используя делегат

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(); 

    } 
} 
0

или так

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(); 

Он работает слишком