2011-04-06 2 views
0

일부 클래스와 인터페이스가 있습니다. 쉽게 내 작업을 설명하기 위해 :복잡한 인터페이스 unboxing 유형

IAnimal 
Cat 
Dog 
Ape 
.. 

지금 Program.cs에서, 나는 물체 수행이와

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

, 나는 개체에 어떤 행동을 원하는 목록을 입력합니다.

animals.ForEach(a => doSomething(a)); 

내가 원하는 것은 어떤 유형이 올지에 달려 있습니다.

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

마지막으로,이 텍스트 식별 및 전환 방법을 더 좋게 만들 수 있는지 궁금합니다. 인터페이스에 generic T를 넣는 것과 같이 typeof-use 나 다른 것을 사용하는 것이 좋을까요?

감사의 말

+0

인터페이스가 가장 적합한 선택인지 확실하지 않습니다. – BoltClock

+0

이 샘플이 현실과 완벽하게 일치하는지 확실하지 않으니 제발 제안 해주세요. – Independent

답변

1

이 "잘못된 추상화 '와 Liskov Substitution 위반의 예처럼 들린다. doSomething() 메서드에 IAnimal의 특정 구현에 대한 종속성이있는 경우 IAnimal 인터페이스는 실제로 올바르게 추상화하지 않습니다. 메소드는 구현 목적에 따라 구현이 달라져야합니다. 왜냐하면 그 목적을 위해 IAnimal에만 필요한 것이기 때문입니다.

에 "구문 분석"메서드를 추가하면 구현시 switch이 아닌 animal.Parse()을 호출하고 이에 따라 각 구현에서 적절하게 처리 할 수 ​​있습니까? 해당 메소드에 대해 Dog에만 의미있는 구현이있는 경우 다른 메소드는 빈 메소드를 갖거나 NotImplementedException을 던지거나 처리하려고 할 수 있습니다. 내가 생각

+0

감사합니다. David. 저는 LSP 위반에 빠졌고 오늘이 특정 부분의 코드를 리팩터링했습니다. 어느 쪽이 더 나은 추상화로 끝나고 - 당신이 말했던 것처럼 - 스위치를 사용하지 않거나 전혀 의사 결정을 내리지 못했습니다. – Independent

4

가상 방법을 다시 발명하고 있습니다. 느린 길. 그것은 인터페이스와 함께 자동으로 Parse() 메소드를 추가합니다. 지금은 간단하다 :

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

그것은 아마도 인수를한다고 ...

+0

감사합니다. 나는 우리가 인터페이스 객체에 대해 Parse()를 가지고 있다는 것에 신경 쓰지 않았다. – Independent

0

은 당신이 얼마나, 유형과 함께 할 더 나은이지만, 케이스 대해서 typeof 넣어에서 (개 | 고양이 | ...)

1

당신은이 작업을 수행 할 수 있습니다

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

그러나 당신이 IAnimal을 정의 할 수있는 인터페이스를 가지고 있다면 어쨌든, 당신이 DoSomethingIAnimal하는 방법을, 각 IAnimal 구현을 구현해야 ... 아마 가장 좋은 방법이 아니다

+0

당신과 Hans/David에 관한 당신의 말이 맞을지도 모릅니다. 나는이 내일로 돌아갈거야, – Independent

1
이봐 요나는 왜하는 방법을 정의 해달라고

하는 한참 할거야. 이 특정 유형의 행동을 dle ??? 실제로 이것이 최선의 방법이며, 당신은 그것에 대해 polimorphism을 사용할 것입니다! 보세요;

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

여전히 비교를 원하면 "IS"키워드를 사용하는 것이 가장 좋습니다.

if (새가 IAnimal 임) 등 ...!

+0

감사합니다 Renato. 사실이고 부분적으로는 ** if (Bird is IAnimal) **입니다. David과 Hans가 내가 (GMT + 1CEST) 내일을 통해 갈 흥미로운 접근법으로 캠핑을했기 때문입니다. – Independent

관련 문제