Привести объект к типу другого объекта - PullRequest
2 голосов
/ 08 декабря 2011

Если у меня есть метод, который принимает какой-либо объект в качестве параметра, я бы хотел создать еще один объект того же типа. Другими словами, если у меня есть объект типа Person, я хотел бы создать или создать новый объект типа person. Если с другой стороны этот объект является животным, я хотел бы создать новый объект из этого класса. Все это без использования оператора 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 ]

1 голос
/ 08 декабря 2011

Вы можете создать метод с именем «CreateNew ()» и создать пустой экземпляр текущего типа объекта.Вы можете сделать это, сделав метод виртуальным или используя этот подход:

public Animal CreateNew() 
{
    return (Type)Activator.CreateInstance(GetType());
}
1 голос
/ 08 декабря 2011

Если бы я был на вашем месте, я бы реализовал интерфейс IClonable и просто позвонил бы:

Animal b = a.Clone();
1 голос
/ 08 декабря 2011

Примерно так:

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

(на самом деле не проверял)

0 голосов
/ 08 декабря 2011

Вы не можете делать "динамическое приведение типов" таким образом.

Я бы предложил использовать немного объектно-ориентированного программирования. Попробуйте реализовать следующий метод в каждом классе, который наследуется от Animal:

у животных:

public abstract Animal GenerateAnimal();

у кошек:

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

у собак:

public override Animal GenerateAnimal()
{
    return new Dog();
}
0 голосов
/ 08 декабря 2011

Просто установите перезаписываемый метод на Animal с именем 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();
    }
}

Также обратите внимание на изменение дляметод Talk(), сделав его виртуальным, а затем переопределив его в подклассах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...