Laden...

[erledigt] Interface mit optionalen Methoden?

Erstellt von mosspower vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.293 Views
mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren
[erledigt] Interface mit optionalen Methoden?

Hallo "Kollegen",

gibt es eigentlich Interfaces, bei denen man Methoden optional deklarieren kann? Mit optional meine ich, dass die Methoden nicht implementiert werden müssen.

Nehmen wir mal ein Beispiel-Interface einer Testklasse ...


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SemaphoreTest {
  interface ITest {
    public void Init();
    public void PreRun();
    public void Run();
    public void PostRun();
    public void CleanUp();
    public void RunRequestMonitor();
  }
}

Jetzt muss, und um das muss geht es mir, jede Klasse, die das Interface implementiert auch alle Methoden implementieren. Gibt es jetzt eine Möglichkeit, nur bestimmte Methoden als mandatory zu kennzeichnen? Es ist ja nicht gerade "dolle", wenn man leere Implementations-Methoden macht, nur damit sie halt "da sind".

OK, man könnte ja auch die "mandatory" im Interface lassen und für die restlichen Attribute verwenden.

Hat jemand noch, neben den Attributen, eine Idee?

467 Beiträge seit 2007
vor 14 Jahren

ein Interface macht ja nur dann Sinn, wenn die Erbende Klasse alle seine Fähigkeiten erfüllt. Das sit der Sinn der Polymorphie. Ich würde dir eine abstrakte Klasse, mit teils unabstrakten virtuellen Methoden empfehlen.

M
198 Beiträge seit 2007
vor 14 Jahren

Was du evtl. machen könntest wäre eine Abstrakte Klasse:


public abstract class Whatever
{
  protected bool _initialized;
  
  public void Run()
  {
     if(!initialized) 
     {
         Init();
     }
     PreRun();
     WhileRunning();
     PostRun();
     CleanUp();
  }

  protected virtual void Init()
  {
      _initialized = true;
  }
  protected virtual void PreRun() {}
  protected virtual void PostRun() {}
  protected virtual void CleanUp() {}
  protected abstract void WhileRunning();
  
}

467 Beiträge seit 2007
vor 14 Jahren

was habe ich gerade gesagt?

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

OK, vielen Dank erst mal für die Hinweise ... und ich dachte immer, what the heck with abstact classes, wenn es doch Interfaces gibt 😁


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestProject {
  public abstract class BaseTaks {
    public abstract void Run();

    public virtual void PreRun() {
      // Empty
    }

    public virtual void PostRun() {
      // Empty
    }
  }

  public class BlubTask : BaseTaks {
    public override void Run() {
      Console.WriteLine("I'm running");
    }

    public override void PostRun() {
      Console.WriteLine("Post runner");
    }

    public static void Main() {
      BlubTask blubTask = new BlubTask();
      blubTask.PreRun();
      blubTask.Run();
      blubTask.PostRun();

      Console.WriteLine("Done ...");
      Console.ReadLine();
    }
  }
}

Das wäre wirklich eine Lösung, was mir hier nur nicht gefällt, sind die leeren (non-mandatory) Methoden in der abstrakten Basisklasse.

Naja, jetzt muss ich mich wohl entscheiden ... Attribute wären ja auch eine Alternative, wie z.B. bei den UnitTesting-Klassen


//
    // You can use the following additional attributes as you write your tests:
    //
    // Use ClassInitialize to run code before running the first test in the class
    // [ClassInitialize()]
    // public static void MyClassInitialize(TestContext testContext) { }
    //
    // Use ClassCleanup to run code after all tests in a class have run
    // [ClassCleanup()]
    // public static void MyClassCleanup() { }
    //
    // Use TestInitialize to run code before running each test 
    // [TestInitialize()]
    // public void MyTestInitialize() { }
    //
    // Use TestCleanup to run code after each test has run
    // [TestCleanup()]
    // public void MyTestCleanup() { }
    //
    #endregion

    [TestMethod]
    public void TestMethod1(int Hallo) {
      Console.WriteLine("Hollo");
      Assert.AreEqual(1, 1);
    }

328 Beiträge seit 2006
vor 14 Jahren

Wäre es dann nicht vielleicht sinnvoll, das Interface aufzuteilen?

Robert Wachtel

http://blog.robertsoft.de

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

Hallo robert.wachtel,

stimmt, das wäre auch eine Möglichkeit, jedoch müsste ich dann, für alle optionalen Methoden (n) auch n-verschiedene Interfaces zur Verfügung stellen, die alle lediglich eine Methodensignatur enthalten.

Gelöschter Account
vor 14 Jahren

was stellst du dir denn vor, was passieren soll, wenn man eine methode aufruft, die optional war, jedoch garnicht implementiert ist?

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

Hallo JAck30lena,

naja, ich würde die ja nur dann aufrufen, wenn eine Implementierung vorhanden ist, bzw. wenn ein bestimmtes Attribute für eine Methode vorhanden ist. Somit ist sichergestellt, dass gewisse Arbeitsabläufe (Methodenaufrufe) durchgeführt werden können, wenn gewünscht, oder aber ausgelassen werden, falls nicht benötigt.

Bei den Untitests ist es ja z.B. auch so, dass es verschiedene Attribute gibt:

[ClassInitialize]
Einmalige Initialisierung innerhalb der Instanz (optional)

[ClassCleanUp]
Einmaliges Aufräumen innerhalb der Instanz (optional)

[TestInitialize]
Initialisierung vor Aufruf jeder Testmethode (optional)

[TestCleanup]
Aufräumen nach Aufruf jeder Testmethode (optional)

[TestMethod]
Die Testmethode (mandatory)

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo mosspower,

Bei den Untitests ist es ja z.B. auch so, dass es verschiedene
**Attribute **gibt:

Und warum machst du das nicht auch so?

Gruß,
dN!3L

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

Hallo dN!3L,

weil ich hier erst mal eure Meinungen hören wollte. Außerdem müsste ich ja n-verschiedene Attribute erstellen und dann noch eine umfangreiche Validierung (Rückgabewerte, Parameter ect.) durchführen.

Ich hatte zur Zeit der Threaderstellung mit Attributen "geliebäugelt", jedoch werde ich die Umsetzung mit einer abstrakten Klasse mit abstrakten und virtuellen Methoden vornehmen (dann sind halt die optionalen, virtuellen Methoden leer - man muss ja auch vorankommen 😄).

Vielen Dank noch mal für euere Hilfe und Anregungen - ich setze den Thread mal auf erledigt.

Gruß

Gelöschter Account
vor 14 Jahren

naja, ich würde die ja nur dann aufrufen, wenn eine Implementierung vorhanden ist,

das problem ist, das du ja anhand des interfaces nciht weißt, ob es implementiert ist.

das was du genau vorhast wäre am einfachsten mit .net 4.0 zu schaffen oder aber du machst so eine art controller, wo du manuell die klassen und deren methoden einträgst dun dann per reflection diese instanziierst und ausführst.

am einfachsten jedoch wäre es wirklich mit attributen zu lösen. markiere eine methode und eine klasse und lese diese per reflection aus.

4.207 Beiträge seit 2003
vor 14 Jahren

Zum Thema Interfaces vs abstrakte Basisklassen: http://www.des-eisbaeren-blog.de/post.aspx?id=a245cc82-8c61-406f-95cb-621d13bd14b4

Wenn eine abstrakte Basisklasse an dieser Stelle nicht gewünscht ist, würde ich vorschlagen, die Funktionalität in mehrere (!) Interfaces aufzuspalten: Ein Basisinterface, wo alles zwingend notwendige drin ist, und dann zusätzliche Feature-Interfaces.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

Hallo Golo Roden,

danke für den Link. Ist ja eigentlich genau das Theama des Threads wobei man hier ggf. auch noch Attribute mit ins Spiel bringen könnte.

Da eine abstrakte Basisklasse für meinen Fall kein Hindernis ist (Stichwort Mehrfachvererbung), habe ich mich, wie oben schon angedeutet, für eine abstrakte Basisklasse mit abstrakten und virtuellen Methoden entschieden.

Die virtuellen Methoden geben halt Default-Werte zurück, wenn es überhaupt einen Rückgabewert gibt, ansonsten sind das halt nur leere Hüllen. Letzteres ist zwar nicht die optimale Lösung, da leere Methoden, aber der Einsatz von Attributen schien mir hier für meine Problem zu aufwändig.

Gruß und Danke noch an alle für die rege Teilnahme und den beschriebenen Lösungsvorschlägen.

Gelöschter Account
vor 14 Jahren

Letzteres ist zwar nicht die optimale Lösung, da leere Methoden,

naja, es ist aus codetechnischer sicht nciht optimal aber wenn idese methoden wirklich leer sind, dann werden diese sowieso "Inlined" mit dem effekt, das sie ausgelassen und somit garnicht erst aufgerufen werden, was nach dem JIT-Compile das optimum darstellt. wenn du attribute hättest, würdest du aufwändig suchen um nichts zu finden.

mosspower Themenstarter:in
456 Beiträge seit 2007
vor 14 Jahren

... wenn du attribute hättest, würdest du aufwändig suchen um nichts zu finden.

Hallo JAck30lena,

naja, wenn man das sowieso mittels Reflection macht, dann sollte man ja auch die Attribute Informationen pro Type cachen, so würde das aufwändige Abfragen der Attribute auch nur einmalig durchgeführt werden, so dass dies bezüglich Performance imo nicht ins Gewicht fällt.