4 Stimmen

Mehrfachvererbung in C# - wieder

Ich weiß, dass es in C# keine Mehrfachvererbung gibt. Und ich weiß, es gibt Umgehungen wie éste zum Beispiel.

Aber hier ist ein Problem, dass ich heute konfrontiert, kann nicht herausfinden, jede ELEGANT Abhilfe. Ich werde ein abstraktes Code-Beispiel hinzufügen, damit Sie es schneller verstehen...

(es sollte ein echter ASP.NET-Code sein - denn diese "Klasse A, Klasse B"-Codebeispiele sind wirklich verwirrend):

public class AdminPage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        //if not an admin - get out
        if(!CurrentUserIsAdmin()) Response.End();

        base.OnInit (e);
    }
}

public class JQueryPage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        RegisterJQueryScript();
        base.OnLoad (e);
    }
}

//now here's what I REALLY miss in C#
public class AdminJQueryPage : AdminPage, JQueryPage;

9voto

Joe Punkte 44378

Die Funktionalität zusammenstellen? Dies ist besser für die Einzelverantwortung. Sie müssen sorgfältig über Ihre Konstruktoren nachdenken.

interface IAdminPage {
  public string AdminPageMethod();
}

interface IJQueryPage {
  public string JQueryPageMethod();
}

internal class AdminPage : IAdminpage {
  private string someString;

  internal AdminPage(string value) {
    this.someString = value;
  }

  public string AdminPageMethod() {
    return "AdminPage result with some string: " + this.someString;
  }
}

internal JQueryPage : IJQueryPage {
  private int someNumber;

  internal JQueryPage(int value) {
    this.someNumber = value;
  }

  public string JQueryPageMethod() {
    return "JQueryPage result with number: " + this.someNumber;
  }
}

class AdminJQueryPage : IQueryPage, IAdminpage {
  private readonly IAdminPage adminPage;
  private readonly IJQueryPage jqueryPage;

  public AdminJQueryPage(string someString, int someNumber) {
    this.adminPage = new AdminPage(someString);
    this.jqueryPage = new JQueryPage(someNumber);
  }

  public string AdminPageMethod() {
    return this.adminPage.AdminPageMethod();
  }

  public string JQueryPageMethod() {
    return this.adminPage.JQueryPageMethod();
  }
}

Wenn Sie wirklich Mehrfachvererbung wollen, schauen Sie sich Scalas Eigenschaften

bearbeiten : Übergabe von Konstruktorwerten an ausgearbeitete Klassen hinzugefügt. Außerdem wurden die Klassen intern gemacht (es kann nicht auf sie zugegriffen oder sie außerhalb der Assembly konstruiert werden), da sie immer nur von der AdminJQueryPage Klasse, die die "öffentliche" Klasse ist.

3voto

Ruben Bartelink Punkte 57310

Ich komme auch von C++ und vermisse es nicht, besonders seit ich Refactoring gelesen habe [und ein Nicht-OOTB-Tool dafür verwende].

Sie können PostSharp verwenden, um den Prozess auf der Grundlage der Platzierung von Attributen auf Ihrer AdminJQueryPage zu posten, was genau den gleichen Effekt erzielen würde.

Oder Sie können den Methodencode in Hilfsklassen extrahieren und diese aufrufen (z. B. in Joes Beispiel)

Oder Sie können die Hilfsprogramme in eine einzige Basisklasse einfügen und von dort aus aufrufen.

In jedem Fall wird Ihr Code klarer.

Es ist nur eine Frage der Zeit, bis Ihre Mixins anfangen, sich zu überlappen, und dann muss Ihre allgemeine Suite von Techniken zur Verwaltung dieser Komplexität zum Einsatz kommen - in C++ sollte MI nur ein Werkzeug in einer Suite sein - und nicht ein sehr sexy Hammer.

2voto

jk. Punkte 13339

Ist es möglich ein Mixin vortäuschen durch die Angabe einer Schnittstelle und die Erstellung von Erweiterungsmethoden für diese Schnittstelle. Allerdings bin ich nicht verwenden diese wird helfen, überschreiben Methoden, nur das Hinzufügen neuer. Sie sind natürlich in der Lage, dann eine Erweiterung Methode aufrufen, wenn überschreiben, aber das ist im Grunde das gleiche wie die Extraktion der Methoden zu einem Helfer-Klasse, aber mit ein wenig mehr Zucker

2voto

RickNZ Punkte 18158

Selbst wenn es möglich wäre, ein Problem mit der Semantik einer MI-basierten Lösung für das von Ihnen angesprochene spezifische Problem ist, was passiert auf der Auszeichnungsseite? Die Render()-Methode, die das Markup generiert, würde zuerst in der einen Klasse und dann in der anderen ausgeführt? Das ist wahrscheinlich nicht das Verhalten, das Sie wollen, wenn beide Klassen ganze Seiten generieren.

Wenn Sie offen für Lösungen sind, die außerhalb der Sprache selbst liegen, gibt es in ASP.NET mehrere elegante Optionen, die das von Ihnen angesprochene Problem lösen (Änderung der Aktionen, die während eines Ereignisses im Lebenszyklus der Seite ausgeführt werden). Zum Beispiel:

  1. Seitenadapter
  2. Steueradapter
  3. Benutzerdefinierte Steuerelemente
  4. HttpModules
  5. Master-Seiten
  6. Tag-Zuordnung

Die beste Wahl hängt natürlich von den Einzelheiten Ihrer Bewerbung ab. Falls es hilfreich ist, behandle ich diese Optionen in meinem Buch, einschließlich Beispielcode: Ultra-schnelles ASP.NET .

1voto

Jeremy McGee Punkte 24034

Der einfachste Ansatz besteht darin, eine Hierarchie zu erstellen - lassen Sie AdminPage von JQueryPage wie folgt erben:

public class AdminPage : JQueryPage
{
    protected override void OnInit(EventArgs e)
    {
        //if not an admin - get out
        if(!CurrentUserIsAdmin()) Response.End();

        base.OnInit (e);
    }
}

public class JQueryPage : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
        RegisterJQueryScript();
        base.OnLoad (e);
    }
}

//now here's what I REALLY miss in C#
public class AdminJQueryPage : AdminPage

Meine Vermutung ist, dass ein Teil dieser Unbeholfenheit vom ASP.NET-Seitenmodell herrührt, das überschriebene Basisklassenmethoden verwendet.

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