С# - Кастинг параметра 'object' в этот тип объекта?

С#

Привет всем,

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

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

Другим решением вместо использования интерфейса будет иметь базовый класс и переопределить метод 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", описанный выше.

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

Ответ 5

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

if (objectToMove is Cat)

Ответ 6

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

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

Ответ 7

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

interface IAnimal
{
    void Move();
}

Интерфейс

Тогда моя кошка и моя птица:

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

Итак, когда вы закончите, вы получите следующее:

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

И если вы хотите проверить тип своего животного, вы можете это сделать:

public void PrintType(IAnimal animal)
{   
    Console.WriteLine(typeof(animal));
    //or
    Console.WriteLine(animal.GetType());
}