C# General 隐式按类型转换实例

C# General inexplicit upcast of instance by type

你能给我解释一下吗? 我必须如何解决下面的简单任务?

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 当然对 Method() 一无所知。

我建议在两个派生的 Base class overriden 中使用 abstract 方法:

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

如果 class 仅用于声明且没有任何具体方法,则使用 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();    
}

你需要明白的是继承多态是干什么的。

继承

允许相关对象派生自共同祖先。

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

接口与抽象类

接口定义了对象可以做什么。在下面的示例中,DogCat 实现了 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

抽象class定义什么是对象。在下面的示例中,DogCat 扩展了 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

要回答您的问题,请确定您的对象如何以及为何相关。如果它们因可以做什么而相关,则使用接口。如果它们是相关的,那么使用抽象 class.

同意每个答案。谢谢大家

但是还有一个 ..crutch.. 通过使用 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();

    }
}

或如此

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

它也有效