C# - 将'object'参数转换为该对象的类型?

时间:2009-11-03 10:29:02

标签: c# reflection refactoring

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 个答案:

答案 0 :(得分:25)

正确的方法是:

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方法无需任何修改即可正常运行。在您的版本中,您将不得不更改方法。
  3. 想象一下,如果你的程序中有is个语句,你会有多少工作?

答案 1 :(得分:9)

好吧,您可以使用is这样的关键字:

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

答案 2 :(得分:4)

一个小点......不使用as和更合适更正确,因为隐含的第二类检查是多余的。要么按以下方式使用:

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,我们确信我们已经确定它应该是可能的。

答案 3 :(得分: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”接口的每个类中复制代码。

当然如果没有通用元素接口工作正常。

答案 4 :(得分:3)

您可以使用“is”运算符来检查对象是否是某个类的实现。

if (objectToMove is Cat)

答案 5 :(得分:2)

你的改变很有意义。

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

答案 6 :(得分:0)

我要做的是:

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