C# - приведение параметра "объекта" в тип этого объекта?

C#

Всем привет,

Я передаю объект в метод.

Я хочу привести этот объект к определенному классу, чтобы я мог выполнять свои собственные конкретные методы? Как я могу это сделать?

Move( new Cat() );
Move( new Pigeon() );

public void Move(object objectToMove)
{
    if(objectToMove== Cat)
    {
        Cat catObject = objectToMove as Cat;
        catObject.Walk();
    }
    else if(objectToMove== Pigeon)
    {
        Rat pigeonObject = objectToMove as Pigeon;
        pigeonObject.Fly();
    }
}

7 ответов

Решение

Ну, вы можете использовать is ключевое слово как это:

if(objectToMove is Cat)
{
    ...
}
else if(objectToMove is Pigeon)
{
    ...
}

Правильный способ сделать это будет:

public interface ICanMove
{
   void Move();
}

реализовано как Cat, так и Pigeon:

public class Cat : ICanMove
{
   public void Move() { /* do something */ }
}

public class Pigeon : ICanMove
{
   public void Move() { /* do something */ }
}

А потом назовите это так:

public void Move(ICanMove objectThatMoves)
{
   objectThatMoves.Move();
}

Вы получаете несколько вещей:

  1. Вы можете только позвонить Move(ICanMove objectThatMoves) для объекта, который реализует интерфейс. Если вы попытаетесь передать другой объект, ваша программа не скомпилируется.
  2. Вы теряете условное утверждение. Если вы решили добавить Dog который реализует ICanMove В вашей программе метод Move будет отлично работать без каких-либо изменений. В вашей версии вам придется изменить метод.

Представьте, сколько бы у вас было работы, если бы у вас было is заявления по всей вашей программе?

Другое решение вместо использования интерфейса состояло бы в том, чтобы иметь базовый класс и переопределить метод Move() в каждом производном классе.

    abstract class Animal
    {
        public abstract void Move();
    }

    public class Cat : Animal
    {
        public override void Move()
        {
            //Cat specific behavior
        }
    }

    public class Bird : Animal
    {
        public override void Move()
        {
            //Bird specific behavior
        }
    }

Я думаю, что использование базового класса лучше, если у вас есть свойства или методы, которые являются общими для всех ваших "животных". Таким образом, вам не нужно дублировать код в каждом классе, который реализует интерфейс "IAnimal", описанный выше.

Конечно, если нет общих элементов, интерфейс работает нормально.

Одна небольшая точка... Правильнее не использовать как и вместе, так как подразумеваемая проверка второго типа является избыточной. Либо используйте как следующим образом:

Cat catObject = objectToMove as Cat;
if(catObject!=null)
    catObject.Walk();
else 
{
    Pigeon pigeonObject = objectToMove as Pigeon;        
    if(pigeonObject!=null)
        pigeonObject.Fly();    
}

Или сделайте прямой актерский состав, так как вы уверены, что это удастся; это более эффективно и понятно:

if(objectToMove is Cat)    
{        
     Cat catObject = (Cat)objectToMove;        
     catObject.Walk();    
}    
else if(objectToMove is Pigeon)    
{        
     Pigeon pigeonObject = (Pigeon)objectToMove;        
     pigeonObject.Fly();    
}

Используя прямое приведение, вы получаете исключение, если оно терпит неудачу, а не нуль. Люди, читающие код, узнают без контекста: "Мы не просто пытаемся понять, можно ли его лечить as что-то, мы уверены, что мы убедились, что это должно быть возможно.

Вы можете использовать оператор "is", чтобы проверить, является ли объект реализацией определенного класса.

if (objectToMove is Cat)

Просто немного изменений в вашем, и это хорошо, чтобы идти.

Move( new Cat() );
Move( new Pigeon() );

public void Move(object objectToMove)
{
    if(objectToMove is Cat)
    {
        Cat catObject = objectToMove as Cat;
        catObject.Walk();
    }
    else if(objectToMove is Pigeon)
    {
        Rat pigeonObject = objectToMove as Pigeon;
        pigeonObject.Fly();
    }
}

Что бы я сделал, это:

interface IAnimal
{
    void Move();
}

Интерфейс

Then my cat and my bird:

class Cat : IAnimal
{
    public void Move()
    {
        //a cat moves by walking
        this.Walk();
    }

    public void Walk()
    {
        //do logic
    }
}

class Bird : IAnimal
{
    public void Move()
    {
        this.Fly();
    }

    public void Fly()
    {
        //do fly logic
    }
}

So when you're done you get this:

public void Move(IAnimal animal)
{
    animal.Move();
}

And should you want to check the type of your animal you can do this:

public void PrintType(IAnimal animal)
{   
    Console.WriteLine(typeof(animal));
    //or
    Console.WriteLine(animal.GetType());
}
Другие вопросы по тегам