642 Stimmen

Schnittstelle, die eine Konstruktorsignatur definiert?

Es ist seltsam, dass ich zum ersten Mal mit diesem Problem konfrontiert werde, aber:

Wie definiert man einen Konstruktor in einer C#-Schnittstelle?

編集
Einige Leute wollten ein Beispiel (es ist ein Freizeitprojekt, also ja, es ist ein Spiel)

IDrawable
+Aktualisierung
+Zeichnen

Um sich selbst zu aktualisieren (auf den Rand des Bildschirms zu prüfen usw.) und zu zeichnen, benötigt es immer eine GraphicsDeviceManager . Ich möchte also sicherstellen, dass das Objekt einen Verweis darauf hat. Dies würde in den Konstruktor gehören.

Jetzt, wo ich das aufgeschrieben habe, denke ich, dass ich hier Folgendes umsetze IObservable und die GraphicsDeviceManager sollte die IDrawable ... Es scheint, dass ich entweder das XNA-Framework nicht verstehe, oder dass das Framework nicht sehr gut durchdacht ist.

編集
Es scheint einige Verwirrung über meine Definition von Konstruktor im Zusammenhang mit einer Schnittstelle zu geben. Eine Schnittstelle kann tatsächlich nicht instanziiert werden und braucht daher keinen Konstruktor. Was ich definieren wollte, war eine Signatur für einen Konstruktor. Genau wie eine Schnittstelle eine Signatur einer bestimmten Methode definieren kann, könnte die Schnittstelle die Signatur eines Konstruktors definieren.

3 Stimmen

Anstatt eine Schnittstelle zu haben, die Ihren Konstruktor definiert, haben Sie stattdessen eine Schnittstelle, die Ihre Fabrikmethoden definiert.

2voto

MauganRa Punkte 486

Der Zweck einer Schnittstelle ist es, eine bestimmte Objektsignatur durchzusetzen. Sie sollte sich ausdrücklich nicht damit befassen, wie ein Objekt intern funktioniert. Daher ist ein Konstruktor in einer Schnittstelle aus konzeptioneller Sicht nicht wirklich sinnvoll.

Es gibt jedoch einige Alternativen:

  • Erstellen Sie eine abstrakte Klasse, die als minimale Standardimplementierung fungiert. Diese Klasse sollte die Konstruktoren haben, die Sie von implementierenden Klassen haben sollten.

  • Wenn Ihnen der Overkill nichts ausmacht, verwenden Sie das AbstractFactory-Muster und deklarieren Sie eine Methode in der Schnittstelle der Fabrikklasse, die über die erforderlichen Signaturen hat.

  • Pass die GraphicsDeviceManager als Parameter für die Update y Draw Methoden.

  • Verwenden Sie ein kompositionsorientiertes objektorientiertes Programmiergerüst zur Übergabe der GraphicsDeviceManager in den Teil des Objekts, der es benötigt. Dies ist meiner Meinung nach eine ziemlich experimentelle Lösung.

Die von Ihnen beschriebene Situation ist im Allgemeinen nicht einfach zu handhaben. Ein ähnlicher Fall wären Entitäten in einer Geschäftsanwendung, die Zugriff auf die Datenbank benötigen.

1 Stimmen

Ich bin mir nicht sicher, ob ich das "deshalb" verstehe. Die Implementierung eines Konstruktors (was er tut) ist intern, aber wie ist ein Konstruktor selbst intern? Inwiefern ist er mehr oder weniger "intern" als eine Methode? Er wird sicherlich extern aufgerufen, wenn eine Instanz erzeugt wird...

0 Stimmen

@Joe Es ist eine Designentscheidung von Java. Es wäre denkbar, eine Sprache zu schaffen, die obligatorische Konstruktoren anbietet. Allerdings würde dies die Injektion von Abhängigkeiten über Konstruktorinjektion unmöglich machen. Außerdem ist die Objekterzeugung per Konstruktor ein sehr technisches Problem, das sich nicht immer sauber auf die Geschäftslogik übertragen lässt. Zum Beispiel, für eine Klasse BlogPost Die Erstellung eines Objekts (möglicherweise nach dem Laden der Daten aus der Datenbank) und die tatsächliche Erstellung eines Blogbeitrags sind zwei unterschiedliche Ereignisse.

0voto

Kunal Punkte 75

Eine Möglichkeit, eine Art von Konstruktor zu erzwingen, besteht darin, nur Getters in der Schnittstelle, was dann bedeuten könnte, dass die implementierende Klasse eine Methode, idealerweise einen Konstruktor, haben muss, um den Wert setzen zu lassen ( private lich) dafür.

0voto

Lea Hayes Punkte 59340

Es wäre sehr nützlich, wenn es möglich wäre, Konstruktoren in Schnittstellen zu definieren.

Da eine Schnittstelle ein Vertrag ist, der in der angegebenen Weise verwendet werden muss. Der folgende Ansatz könnte für einige Szenarien eine praktikable Alternative sein:

public interface IFoo {

    /// <summary>
    /// Initialize foo.
    /// </summary>
    /// <remarks>
    /// Classes that implement this interface must invoke this method from
    /// each of their constructors.
    /// </remarks>
    /// <exception cref="InvalidOperationException">
    /// Thrown when instance has already been initialized.
    /// </exception>
    void Initialize(int a);

}

public class ConcreteFoo : IFoo {

    private bool _init = false;

    public int b;

    // Obviously in this case a default value could be used for the
    // constructor argument; using overloads for purpose of example

    public ConcreteFoo() {
        Initialize(42);
    }

    public ConcreteFoo(int a) {
        Initialize(a);
    }

    public void Initialize(int a) {
        if (_init)
            throw new InvalidOperationException();
        _init = true;

        b = a;
    }

}

0 Stimmen

Das Problem dabei ist, dass ich nicht wissen kann, dass ich eine Variable an den Konstruktor dieses neuen Elements übergeben kann.

0 Stimmen

@Boris instanziieren Sie Objekte mit Reflection?

0voto

Obwohl man in einer Schnittstelle keine Konstruktorsignatur definieren kann, halte ich es für erwähnenswert, dass man an dieser Stelle eine abstrakte Klasse in Betracht ziehen kann. Abstrakte Klassen können nicht implementierte (abstrakte) Methodensignaturen auf dieselbe Weise wie eine Schnittstelle definieren, können aber auch implementierte (konkrete) Methoden und Konstruktoren haben.

Der Nachteil ist, dass sie, da sie ein Klassentyp ist, nicht für eines der Szenarien der Mehrfachvererbung verwendet werden kann, wie es eine Schnittstelle kann.

0voto

royatl Punkte 336

Sie nicht.

der Konstruktor ist Teil der Klasse, die eine Schnittstelle implementieren kann. Die Schnittstelle ist nur ein Vertrag von Methoden, die die Klasse implementieren muss.

22 Stimmen

Ja, und der Vertrag würde festlegen, dass der Implementierer einen Ctor benötigt, der dieser spezifischen Signatur entspricht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X