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|...)
精彩评论