문제
주어진:
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을 사용할 수 있다고 확신합니다.