문제

주어진:

interface I
{
}

class B: I
{
}

class C: I
{
}

class A
{

    public void Method(B arg)
    {
    }

    public void Method(C arg)
    {
    }

    public void Method(I arg)
    {
       // THIS is the method I want to simplify.
       if (I is B)
       {
          this.Method(arg as B);
       }
       else if (I is C)
       {
          this.Method(arg as C);
       }
    }
}

이러한 유형의 상호 작용을 설계하는 더 좋은 방법이 있다는 것을 알고 있지만, 설명하는 데 너무 오래 걸리는 세부 사항 때문에 불가능합니다. 이 패턴은 여러 번 복제되므로 조건부 로직을 한 줄만 사용할 수있는 일반적인 구현으로 바꾸고 싶습니다. 이 일반적인 방법/클래스를 구현하는 간단한 방법을 볼 수는 없지만 본능적으로 가능하다고 말합니다.

모든 도움이 감사하겠습니다.

도움이 되었습니까?

해결책

당신이 원하는 것은 이중 파견, 그리고 방문자 패턴 특히.

다른 팁

메소드를 인터페이스 내부에 넣은 다음 다형성이 호출 할 방법을 결정하게합니다.

interface I
{
   void Method();
}

class B : I
{
   public void Method() { /* previously A.Method(B) */}
}

class C : I
{
   public void Method() { /* previously A.Method(C) */ }
}

class A
{
   public void Method(I obj)
   { 
     obj.Method();
   }
}

이제 새 클래스를 추가해야 할 때 i.method 만 구현하면됩니다. A.Method를 만질 필요가 없습니다.

이것은 좀 못 생겼지 만 작업이 완료됩니다.

public void Method(B arg)
{
  if (arg == null) return;
...
}
public void Method(C arg)
{
  if (arg == null) return;
...
}

public void Method(I arg)
{
  this.Method(arg as B);
  this.Method(arg as C);
}

그래도 나는 이런 식으로 그렇게 할 것이라고 생각하지 않습니다. 실제로 그것을보고 아프다. 여러분 모두에게 이것을 보도록 강요해서 죄송합니다.

interface I
{ 
} 

class B : I
{
}

class C : I
{
}    

class A 
{
    public void Method(B arg)
    {
        Console.WriteLine("I'm in B");
    }

    public void Method(C arg)
    {
        Console.WriteLine("I'm in C");
    }

    public void Method(I arg)
    {
        Type type = arg.GetType();

        MethodInfo method = typeof(A).GetMethod("Method", new Type[] { type });
        method.Invoke(this, new I[] { arg });
    }
}

C#과 함께 편리한 형태로 존재하지 않습니다. 여기를 봐 F#의 패턴 일치를 기반으로 한 아이디어의 경우 원하는 것을 정확하게 수행합니다. 런타임에 오버로드를 선택하기 위해 반사로 몇 가지 작업을 수행 할 수 있지만 매우 느리게 진행되며 두 가지 과부하를 만족하면 심각한 문제가 발생합니다. 반환 값이있는 경우 조건부 연산자를 사용할 수 있습니다.

return (I is B) ? Method((B)I) : ((I is C) ? Method((C)I) : 0);

다시 - 예쁘지 않습니다.

쉬운. Visual Basic에서는 CallbyName을 사용하여 항상이 작업을 수행합니다.

Sub MethodBase(value as Object)
    CallByName(Me, "RealMethod", CallType.Method, value)

이렇게하면 런타임 값 유형과 가장 밀접하게 일치하는 RealMethod의 오버로드를 호출합니다.

Microsoft.visualBasic.interaction을 가져 오거나 반사를 사용하여 자신의 버전을 만들어 C#의 CallByName을 사용할 수 있다고 확신합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top