Folgendes Beispiel: Ich habe ein Interface, das von zwei Klassen benutzt werden kann. Einmal eine Klasse zum Editieren eines Objekts und einmal eine Klasse die zum Anzeigen des Objekts in einer Liste verwendet wird. Hier der grobe Aufbaue.

public interface ICustomer
{
    string Name {get; set;}
    string City {get; set;}
    // ...
    event Action Save;
}

public class CustomerEditor : ICustomer
{
   public string Name {get; set;}
   public string City {get; set;}

   public event Action Save;

   // ...

   private void SaveButtonClick(object sender, EventArgs e)
   {
      if (Save != null)
         Save();
   }
}

public class CustomerReadonlyView : ICustomer
{
   public string Name {get; set;}
   public string City {get; set;}

   public event Action Save;

   // ...
}

Wenn man das jetzt kompiliert bekommt man eine Warnung, die folgendermaßen aussieht:
Das Ereignis "CustomerReadonlyView.Save" wird nie verwendet.

Ist auch vollkommen klar. Dummerweise will man das Event aber im Interface definieren, damit man von der entsprechenden Logikklasse sauber getrennt darauf zugreifen kann. Man jetzt da mehrere Möglichkeiten:

  • Zum einen kann man die Warnung einfach ignorieren. Leider machen das die meisten Entwickler und ich muss ganz ehrlich sagen, dass ich es hasse, wenn in einem Projekt beim kompilieren 100 oder mehr Warnungen kommen nur weil einfach nicht sauber programmiert wurde.
  • Dann gibt es noch die Möglichkeit, dass man einfach ein zweites Interface anlegt, das vom ersten ableitet und zusätzlich das Event implementiert, das man nur an bestimmten Stellen braucht. Auch eine schöne Lösung, aber es geht noch besser
  • Die dritte Möglichkeit ist schnell implementiert und hält den Code übersichtlich. Man kann nämlich Compilermeldungen ausschalten
    Der Code würde folgendermaßen aussehen:
// ...
    #pragma warning disable 0067
    public event Action Save;
    #pragma warning restore 0067
    // ...

Damit wird man nicht mehr von dieser Warnung belästigt.

  • Die vierte Möglichkeit ist wieder mit Schreibarbeit verbunden, aber wohl die sauberste Lösung. Man definiert einfach das Event wie es sein soll. Denn was passiert im oben genannten Fall, wenn die Logikklasse dennoch das Event abonnieren will? Nichts… Der Entwickler schreibt sich nen Wolf und implmentiert eine Menge Logik, falls das Event auftritt, dabei wird es niemals auftreten.
    Besser ist daher die folgende Lösung:
// ...
    public event Action Save { 
        add { throw new NotSupportedException(); }
        remove { } 
    }
    // ...

Damit erkennt der Entwickler schon sehr bald, dass es nichts bringt, wenn er dieses Event abboniert.