[c#] 인터페이스 C #에 대리자를 추가하는 방법

수업에 델리게이트가 필요합니다.

인터페이스를 사용하여 이러한 델리게이트를 설정하도록 “알리게”하고 싶습니다.

어떻게?

내 수업은 다음과 같습니다.

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event UpdateStatusEventHandler UpdateStatusText;
    public delegate void UpdateStatusEventHandler(string Status);

    public event StartedEventHandler Started;
    public delegate void StartedEventHandler();
}

해당 대리자를 강제하는 인터페이스가 필요합니다.

public interface myInterface
{
   // ?????
}



답변

그것들은 대리자 유형을 선언하고 있습니다 . 그들은 인터페이스에 속하지 않습니다. 이러한 대리자 유형을 사용 하는 이벤트 는 다음과 같이 인터페이스에있는 것이 좋습니다.

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{
    event UpdateStatusEventHandler StatusUpdated;
    event StartedEventHandler Started;
}

구현은 인터페이스에서 사용되는 다른 유형을 재 선언하는 것보다 더 많이 델리게이트 유형을 재 선언하지 않습니다 (그리고 그렇게해서는 안됩니다).


답변

.NET 3.5부터는 고유 한 유형을 선언 할 필요없이 System.Action 대리자를 사용할 수도 있습니다.

결과적으로 다음과 같은 인터페이스가 생성됩니다.

public interface myInterface
{
   // Implementing the IProcess interface
   event Action<String> UpdateStatusText;

   event Action Started;
}


답변

대리자를 속성으로 노출하기 만하면됩니다.

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{
    UpdateStatusEventHandler StatusUpdated {get; set;}
    StartedEventHandler Started {get; set;}
}


답변

Jon Skeet의 대답이 맞습니다. 메모를 추가하고 싶습니다.

수행 할 작업 또는 클래스에 포함 할 항목을 “알려주는”인터페이스가 없습니다. 인터페이스는 객체 지향 프로그래밍 및 디자인 방법에 사용되는 추상화 수단입니다. 프로그램의 다른 곳에서 인터페이스로 구체적인 클래스 인스턴스를보고 싶지 않다면 (추상화) 인터페이스 선언이 전혀 필요하지 않을 수도 있습니다.

프로젝트에서 일부 코딩 표준을 적용하려는 경우 코드 분석 도구 (예 : Visual Studio)를 사용해 볼 수 있습니다. 확장을 허용하여 사용자 고유의 코드 분석 규칙을 추가 할 수 있습니다.

코드 분석을 사용하여 대리자를 추가하는 것을 “잊으면”(대리자가 사용되지 않는 것처럼 잊어 버리는 지점은 알 수 없지만 필요하지 않음) 경고 / 오류가 발생합니다.


답변

귀하의 의견 중 하나가 이벤트 핸들러의 반환 유형을 참조했습니다. 핸들러의 유형이나 이벤트에서 돌아 오는 데이터에 더 관심이 있습니까? 후자의 경우 도움이 될 수 있습니다. 그렇지 않은 경우이 솔루션으로는 충분하지 않지만 원하는 항목에 더 가까이 다가가는 데 도움이 될 수 있습니다.

인터페이스와 구현 모두에서 이벤트 핸들러를 일반 이벤트 핸들러로 선언하기 만하면 반환 결과를 사용자 정의 할 수 있습니다.

conrete 클래스는 다음과 같습니다.

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
    //no need for this anymore: public delegate void UpdateStatusEventHandler(string Status);

    public event EventHandler<StartedEventArgs> Started;
    //no need for this anymore: public delegate void StartedEventHandler();
}

인터페이스는 다음과 같습니다.

public interface myInterface
{
   event EventHandler<StartedEventArgs> Started;
   event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
}

이제 이벤트 인수가 유형을 반환하므로 정의한 모든 핸들러에 연결할 수 있습니다.

참고 :
https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx


답변

파생 클래스 내에서 상속 된 인터페이스는 선언 한 내용을 정의하고 연결하도록 알려줍니다.

그러나 명시 적으로 사용하고 싶을 수도 있으며 여전히 개체에 연결해야합니다.

예를 들어 Inversion of Control 패턴을 사용하는 경우 :

class Form1 : Form, IForm {
   public Form1() {
     Controls.Add(new Foo(this));
   }

   // Required to be defined here.
   void IForm.Button_OnClick(object sender, EventArgs e) {
     ...
     // Cast qualifier expression to 'IForm' assuming you added a property for StatusBar.
     //((IForm) this).StatusBar.Text = $"Button clicked: ({e.RowIndex}, {e.SubItem}, {e.Model})";
   }
 }

이런 식으로 시도해 볼 수 있습니다.

interface IForm {
  void Button_OnClick(object sender, EventArgs e);
}


class Foo : UserControl {
  private Button btn = new Button();

  public Foo(IForm ctx) {
     btn.Name = "MyButton";
     btn.ButtonClick += ctx.Button_OnClick;
     Controls.Add(btn);
  }
}


답변