将对象转换为其他对象的类型

时间:2011-12-08 16:54:55

标签: c# generics inheritance reflection polymorphism

如果我有一个方法将任何对象作为参数,我想创建另一个相同类型的对象。换句话说,如果我有一个Person类型的对象,我想要转换或实例化一个类型为person的新对象。另一方面,如果该对象是Animal,我想从该类中实例化一个新对象。所有这些都不使用if或switch语句。让我告诉你我的意思

   class Animal {

        public virtual void Talk()
        {
            Console.WriteLine("-");
        }
    }
    class Dog :Animal
    {
        public override Talk()
        {
            Console.WriteLine("Woof");
        }
    }
    class Cat : Animal
    {
        public override void Talk()
        {
            Console.WriteLine("Miau");
        }
    }

    public static void Main(String[] args)
    {

        Animal a = generateRandomAnimal();

        Animal b;  // I want to institate object b without needing an if statement or a switch            


        // I want to avoid this...
        if (a is Dog)
            b = new Dog();
        else if (a is Cat)
            b = new Cat();
        else
            b = new Animal();

        // if I new what b would be a Cat in advance i know I could do :

        b = (Cat)b; 


        // if am looking for something like

        b=(a.GetType())b; // this gives a compile error

    }

    static Animal generateRandomAnimal()
    {
        switch (new Random().Next(1, 4))
        {
            case 1:
                return new Animal();
            case 2:
                return new Dog();
            default:
                return new Cat();
        }            
    }

修改

感谢kprobst,我最终得到了:

    class Person
    {

        public string Address { get; set; }
        public string Name { get; set; }

    }

    class Animal
    {
        public virtual void Talk()
        {
            Console.WriteLine("-");
        }
    }

    class Car
    {
        public int numberOfDoors { get; set; }
    }


    static object generateRandomObject()
    {
        switch (new Random().Next(1, 4))
        {
            case 1:
                return new Person();
            case 2:
                return new Car();
            default:
                return new Animal();
        }
    }

    public static void Main(String[] args)
    {

        object o = generateRandomObject();

        object newObject;  // i want new object to be of the same type as object o


        if (o is Animal)
            newObject = new Animal();
        if (o is Person)
            newObject = new Person();
        if (o is Car)
            newObject = new Car();


        Type t = o.GetType();
        var b = Activator.CreateInstance(t);
        //.....etc

在我的示例中,并非所有对象都从同一个类继承。这是我第一次看到var keword的真正好处。我知道它很有用,但我只是用它来使我的代码更小,更易读......但在这种情况下它确实有帮助!

5 个答案:

答案 0 :(得分:1)

这样的事情:

Type t = a.GetType();
Animal b = (Animal) Activator.CreateInstance(t);

(实际上没有测试过)

答案 1 :(得分:1)

如果我在你的鞋子里,我会实现IClonable接口,只需致电:

Animal b = a.Clone();

答案 2 :(得分:1)

您可以创建一个名为“CreateNew()”的方法,并创建当前对象类型的空实例。您可以通过将方法设为虚拟或使用此方法来执行此操作:

public Animal CreateNew() 
{
    return (Type)Activator.CreateInstance(GetType());
}

答案 3 :(得分:0)

只需在名为Animal的{​​{1}}上有一个可覆盖的方法,然后返回一个新实例。

例如:

Duplicate()

另外,请注意class Animal //should this class really be abstract? { public virtual void Talk() { Console.WriteLine("-"); } public virtual Animal Duplicate() { return new Animal(); } } class Dog : Animal { public override void Talk() { Console.WriteLine("Woof"); } public override Animal Duplicate() { return new Dog(); } } class Cat : Animal { public override void Talk() { Console.WriteLine("Miau"); } public override Animal Duplicate() { return new Cat(); } } 方法的更改,方法是将其设置为虚拟,然后在子类中覆盖它。

答案 4 :(得分:-1)

你不能那样做“动态类型转换”。

我建议使用一些面向对象的编程。尝试在继承自Animal的每个类中实现以下方法:

动物:

public abstract Animal GenerateAnimal();

在Cat:

public override Animal GenerateAnimal()
{
    return new Cat();
}

在狗:

public override Animal GenerateAnimal()
{
    return new Dog();
}