문제

다음과 같은 결과가 있다고 가정합니다.

interface Foo 
{
 bool Func(int x);
}

class Bar: Foo
{
  bool Func(int x)
  {
   return (x>0);
  }  
}

class Baz: Foo
{
  bool Func(int x)
  {
   return (x<0);
  }  
}

이제 Bar와 Baz를 Foos로 사용하고 Func 메서드를 호출할 수 있습니다.

대리인은 이를 약간 단순화합니다.

delegate bool Foo(int x);

bool Bar(int x)
{
 return (x<0);
}

bool Baz(int x)
{
 return (x>0);
}

이제 Foo 대표로서 Bar와 Baz를 둘러볼 수 있습니다.

더 짧은 코드를 얻는 것 외에 위임의 실제 이점은 무엇입니까?

도움이 되었습니까?

해결책

약간의 차이가 있는데, 위임자는 자신이 정의된 클래스의 멤버 변수에 액세스할 수 있습니다.C#에서는 (Java와 달리) 모든 내부 클래스가 정적 클래스로 간주됩니다.따라서 콜백을 관리하기 위해 인터페이스를 사용하는 경우버튼의 ActionListener입니다.구현하는 내부 클래스는 콜백 중에 상호 작용해야 할 수 있는 포함 클래스 부분에 대한 참조를 생성자를 통해 전달해야 합니다.대리자에게는 이러한 제한이 없으므로 콜백을 구현하는 데 필요한 코드 양이 줄어듭니다.

더 짧고 간결한 코드도 가치 있는 이점입니다.

다른 팁

소프트웨어 엔지니어링 관점에서 보면 델리게이트는 함수 인터페이스의 프로토타입을 만든다는 점에서 함수 인터페이스와 매우 유사합니다.

그들은 또한 같은 종류의 방식으로 많이 사용될 수 있습니다:필요한 메서드가 포함된 전체 클래스를 전달하는 대신 대리자만 전달할 수 있습니다.이렇게 하면 많은 코드가 절약되고 훨씬 더 읽기 쉬운 코드가 생성됩니다.

게다가 람다 표현식의 출현으로 이제 즉석에서 쉽게 정의할 수 있게 되었는데 이는 큰 보너스입니다.C#에서는 즉시 클래스를 구축하는 것이 가능하지만 실제로는 엄청난 고통을 겪습니다.

두 가지를 비교하는 것은 흥미로운 개념입니다.이전에는 사용 사례와 코드 구조화 관점에서 아이디어가 얼마나 유사한지 고려하지 않았습니다.

대리자는 호출자의 관점에서 볼 때 단일 메서드가 있는 인터페이스 참조와 많은 공통점을 공유합니다.

첫 번째 예에서 Baz 및 Bar는 상속되고 인스턴스화될 수 있는 클래스입니다.두 번째 예에서 Baz 및 Bar는 메서드입니다.

인터페이스 계약과 일치하는 클래스에만 인터페이스 참조를 적용할 수는 없습니다.클래스는 인터페이스를 지원함을 명시적으로 선언해야 합니다.서명과 일치하는 모든 메서드에 대리자 참조를 적용할 수 있습니다.

인터페이스 계약에는 정적 메서드를 포함할 수 없습니다.(확장 메서드를 사용하여 정적 메서드를 추가할 수는 있지만)대리자 참조를 사용하여 정적 메서드를 참조할 수 있습니다.

아니요, 대리자는 메서드 포인터를 위한 것입니다.그런 다음 대리자와 연결된 메서드의 서명이 올바른지 확인할 수 있습니다.

또한 클래스의 구조를 알 필요도 없습니다.이렇게 하면 작성한 메소드를 다른 클래스의 메소드에 전달하고 원하는 기능을 정의할 수 있습니다.

다음을 살펴보세요. Find 메서드를 사용하는 List<> 클래스.이제 IListFindable 또는 이와 유사한 것을 구현하기 위해 클래스에 포함된 항목을 요구하지 않고도 항목이 일치하는지 여부를 결정하는 요소를 정의할 수 있습니다.

함수의 매개변수로 대리자를 전달할 수 있습니다. 기술적으로 대리자는 컴파일될 때 객체가 되지만 여기서는 그게 요점이 아닙니다.객체를 매개변수로 전달할 수 있지만(분명히) 해당 유형의 객체를 매개변수로 함수에 연결하게 됩니다.대리자를 사용하면 출처에 관계없이 동일한 서명이 있는 코드에서 실행할 함수를 전달할 수 있습니다.

대리자는 대리자에 맞게 메서드가 가져야 하는 인수와 반환 형식을 정의하는 메서드에 대한 인터페이스로 생각할 수 있습니다.

예, 대리자는 하나의 메서드가 있는 인터페이스로 생각할 수 있습니다.

대리자는 형식화된 메서드 포인터입니다.이는 공분산과 반공분산을 활용할 수 있고 객체 상태를 수정할 수 있기 때문에 인터페이스보다 더 많은 유연성을 제공합니다(인터페이스 기반 펑터를 사용하여 이 포인터를 전달해야 함).

또한 대리자에는 쉽게 결합하는 등의 작업을 수행할 수 있는 멋진 구문 설탕이 많이 있습니다.

인터페이스와 대리자는 완전히 다른 두 가지입니다. 이해하기 쉽도록 대리자를 인터페이스와 같은 용어로 설명하려는 유혹을 이해하지만, 진실을 알지 못하면 혼란을 초래할 수 있습니다.

대표자들은 특정 목적에 부적합한 C++ 메서드 포인터의 기술 때문에 (부분적으로) 영감을 받았습니다.전형적인 예는 메시지 전달 또는 이벤트 처리 메커니즘을 구현하는 것입니다.대리자를 사용하면 클래스 유형이나 인터페이스에 대한 지식 없이도 메서드 시그니처를 정의할 수 있습니다. "void eventHandler(Event* e)" 대리자를 정의하고 이를 구현한 모든 클래스에서 호출할 수 있습니다.

이 고전적인 문제에 대한 통찰력과 대리인이 바람직한 이유 이것을 읽어보세요 그런 다음 이것.

클로저 추가에 대한 적어도 하나의 제안(예:익명 대리자)를 Java로 변환하는 경우 단일 멤버 메서드가 있는 인터페이스와 동일합니다.

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