开发者

Interface unboxing for complex Types

开发者 https://www.devze.com 2023-02-23 01:03 出处:网络
I have a interface with some classes. To easy describe my task: IAnimal Cat Dog Ape .. now, in Program.cs, i fill a list of objects

I have a interface with some classes. To easy describe my task:

IAnimal
 Cat
 Dog
 Ape
 ..

now, in Program.cs, i fill a list of objects

 List<IAnimal> animals = new..
 animals.Add(new Cat {})
 animals.Add(new Ape {})
 ...

With this done, I want some action to the objects.

 animals.ForEach(a => doSomething(a)开发者_C百科);

What I want to do, depends on what type coming up.

void doSomething(IAnimal animal)
{
    switch (animal.GetType().Name)
    {
        case "Dog":
            parseDog(); // parts of a dog?
            break;
            ...
    }
}

My question, as final, is if I can make this more nice then this textual identification and switch method. Like putting a generic T in the interface, better typeof-use or something else?

Thank's in advanced


You are re-inventing virtual methods. The slow way. It is automatic with an interface, add a Parse() method. Now it is simple:

void doSomething(IAnimal animal)
{
    animal.Parse();
}

It probably ought to have an argument...


This sounds like an example of "the wrong abstraction" and a violation of Liskov Substitution. If your doSomething() method has a dependency on the specific implementation of IAnimal being passed to it, then the IAnimal interface isn't really abstracting it properly. The method shouldn't care what implementation it gets, because for its purposes it should need only what's on IAnimal.

Can your "parse" method just be added to IAnimal such that, rather than a switch on implementations, you just call animal.Parse() and allow each implementation to handle that accordingly? If only a Dog has a meaningful implementation for that method, then the others can just have empty methods or throw a NotImplementedException or however you want to handle it.


You can do that:

void doSomething(IAnimal animal)
{
    if (animal is Dog)
    {
        parseDog(); // parts of a dog?
    }
    else if (animal is Cat)
    {
        parseCat();
    }
    else if (animal is Ape)
    {
        ...
    }
}

But anyway, it's probably not the best approach... you should make DoSomething a method of IAnimal, and implement it in each IAnimal implementation


Hey Jonas, if you have an interface do define IAnimal, why dont you define a method which is gonna handle this type-specific behavior??? Actually this is the best way, and youll be using polimorphism for it! Take a look;

public interface IAnimal
{
    void Move();
}

public class Bird : IAnimal
{
    public void Move()
    {
        //Realize that this is a type-specific behavior,
        //which could be different for each class that
        //implements IAnimal, NO NEED FOR UNBOXING
        //or a bunch of IFS!!!
        Console.WriteLine("Im flying!");
    }
}

public class Horse : IAnimal
{
    public void Move()
    {
        Console.WriteLine("Im running!");
    }
}


//Then you may use it this way;
listOfIAnimals.ForEach(c => c.Move());

If you still wanna make the comparison the best way is using the "IS" keyword!

if(Bird is IAnimal), etc...!


I think is better to do with the Type, just how you do, but in cases put typeof(Dog|Cat|...)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号