C # arayüzüne temsilci nasıl eklenir


92

Sınıfımda birkaç delegeye ihtiyacım var.

Arayüzü, bu delegeleri ayarlamamı "hatırlatmak" için kullanmak istiyorum.

Nasıl?

Sınıfım şuna benziyor:

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

Bu delegeleri zorlamak için bir arayüze ihtiyacım var:

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

Yanıtlar:


142

Bunlar temsilci türlerini bildiriyor . Bir arayüze ait değiller. Bu temsilci türlerini kullanan olayların arayüzde olmasına rağmen:

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

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

Uygulama, temsilci türünü, bir arabirimde kullanılan diğer herhangi bir türü yeniden bildirmekten daha fazla yeniden bildirmez (ve etmemelidir).


Bu benim için çalışmıyor. Her şeyi bu şekilde yaptığımdan eminim, ancak arayüzümdeki işleyicim tanınmıyor. Arabirimi uygulayan sınıfım, sınıfın System.EventHandler arabirim dönüş türü ile eşleşmediğinden şikayet ediyor.
Chucky

1
@Chucky: Sorunu ortaya koyan kısa ama eksiksiz bir örnekle yeni bir soru sormanız gerekiyor gibi görünüyor. Ben verdiğim cevabı gerçekten yapar işi.
Jon Skeet

4
Temsilcilerin sınıflarla aynı düzeyde erişilebilirliğe sahip olduğunu bilmiyordum. Her zaman bir sınıf içinde özetlenmeleri gerektiğini düşündüm.
Purusartha

7
@Purusartha: Bu erişilebilirlik değil - bu sadece temsilcilerin arayüzler kadar tip (aslında sınıflar) olması meselesi.
Jon Skeet

30

.NET 3.5'ten beri, kendi türünüzü bildirmenize gerek kalmadan System.Action temsilcilerini de kullanabilirsiniz.

Bu, aşağıdaki arayüzle sonuçlanır:

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

   event Action Started;
}

+1. Action / Func'ı geleneksel delege türlerinden çok daha zarif (ve okunabilir) buluyorum ve bunları arayüzünüzde tanımlayabilirsiniz.
chrnola

2
Bu cevap soruyu ele almıyor (myInterface nasıl uygulanır).
lharper71

10

Temsilciyi bir mülk olarak ifşa edin

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

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

7

Jon Skeet'in cevabı doğru, sadece bir not eklemek istiyorum.

Arayüzler, size ne yapmanız gerektiğini veya sınıflarınıza neleri dahil etmeniz gerektiğini "hatırlatmak" için orada değildir. Arayüzler, Nesne Yönelimli programlama ve tasarım yöntemlerinde kullanılan soyutlama araçlarıdır. Programınızda başka bir yerde arayüz olarak bazı somut sınıf örneklerini görmek istemiyorsanız, belki de bir arayüz bildirimine ihtiyacınız yoktur (Soyutlama).

Projenizde bazı kodlama standartlarını uygulamak istiyorsanız, kod analizi araçlarını kullanmayı deneyebilirsiniz (Visual Studio'da olduğu gibi) - Size kendi kod analizi kurallarını eklemek için dahil edebileceğiniz uzantılara izin verirler.

Kod analizini kullanarak, delegeleri eklemeyi "unutursanız" (delege kullanılmıyormuş gibi unutmanın anlamını görmesem de, buna gerek yoktur) bir uyarı / hata alırsınız.


1
Haklı olabilirsiniz, ancak bazı varsayımlarda bulunduğunuz zaman, iyi bir dokümantasyonla bile bir süre sonra hatırlamanın zor olduğuna dair varsayımlar vardır. Kodumu yeniden kullanmaya çalışıyorum ama bazen neyin öz olduğunu ve ne olmadığını hatırlayamıyorum (temsilciler söz konusu olduğunda - büyük resmi görmek benim için zor ...)
Asaf

1

Yorumlarınızdan biri, olay işleyicisinin dönüş türüne referans verdi. İşleyicinin türü veya olaydan geri gelen verilerle mi daha fazla ilgileniyorsunuz? İkincisi ise, bu yardımcı olabilir. Değilse, bu çözüm yeterli olmayacak, ancak aradığınız şeye yaklaşmanıza yardımcı olabilir.

Tek yapmanız gereken, olay işleyicilerinizi hem arabirimde hem de uygulamanızda genel olay işleyicileri olarak bildirmektir ve dönüş sonuçlarını özelleştirebilirsiniz.

Conrete sınıfınız şöyle görünecektir:

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

Arayüzünüz şöyle görünecektir:

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

Artık olay bağımsız değişkenleri türlerinizi döndürdüğüne göre, bunları tanımladığınız herhangi bir işleyiciye bağlayabilirsiniz.

Referans için: https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx


0

Türetilmiş sınıfınız içinde miras alınan arayüz, içinde tanımladığınız şeyleri tanımlamanızı ve bağlamanızı size hatırlatacaktır.

Ancak bunu açıkça kullanmak isteyebilirsiniz ve yine de onu bir nesneyle ilişkilendirmeniz gerekecektir.

Örneğin, bir Kontrolün Ters Çevirme deseni kullanarak:

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})";
   }
 }

Bunun gibi bir şey deneyebilirsin.

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);
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.