2016-04-28 5 views
0
hat

Ich habe eine Student-Klasse, die EntityBaseDm erbt. Ich habe eine Provider-Klasse, die EntityBaseDm nicht erben soll.Wie "erben" eine Methode, wenn die Klasse bereits eine übergeordnete Klasse

Ich möchte die FormattedName get-Methode und Implementierung in eine generische Klasse extrahieren, aber ich möchte es nicht in EntityBaseDm einfügen, da es allgemein ist. Ich werde eine Schnittstelle wie IFirstLastName herstellen müssen, aber eine Schnittstelle lässt mich nicht Funktionen implementieren. Ich weiß, dass es viele Designmuster gibt, von denen eines diese Probleme lösen kann. Ich frage mich, ob jemand mich in die richtige Richtung zeigen kann (zumindest das richtige Muster zu verwenden)

+0

FormattedName eine Eigenschaft ist, keine Funktion/Methode –

+0

ja, aber die Rückkehr Name VZ + " , "+ Vorname ist eine Methodenimplementierung. Es wird sehr komplex sein, aber zum Beispiel habe ich es vereinfacht. Es wird 10 Klassen geben, die diese Funktion verwenden werden, und ich möchte einen Weg finden, es zu extrahieren, ohne es für alle DM-Klassen generisch zu machen. – andyh0316

Antwort

2

Ich stimme den Ratschlägen von @ ScottHannen zu. Objektzusammensetzung wäre eine gute Passform.

Sie könnten jedoch die von Ihnen erwähnte Schnittstelle IFirstLastName erstellen und dann eine Erweiterungsmethode erstellen.

public interface IFirstLastName 
{ 
    string FirstName { get; } 
    string LastName { get; } 
} 

public static class IFirstLastNameExtensions 
{ 
    public static string FormattedName(this IFirstLastName fln) 
    { 
     return $"{fln.LastName}, {fln.FirstName}"; 
    } 
} 

public class StudentDm : EntityBaseDm, IFirstLastName 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

public class ProviderDm : IFirstLastName 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

Dann könnten Sie die FormattedName Methode für jede Klasse aufrufen, die IFirstLastName implementiert:

var dm = new ProviderDm(); 
dm.FormattedName(); 
+0

Vielen Dank !! .. während Scotts Antwort sehr gut ist .. diese passt mir am meisten, da es mehr Flexibilität erlaubt. Zum Beispiel könnte ich verschiedene Annotationen (zB [Erforderlich] oder [MaxLänge]) für Vorname in den verschiedenen Klassen haben. Und die Komposition wird mir das nicht erlauben. – andyh0316

0

Die Antwort ist ein abstract class. Dies ähnelt einer Schnittstelle, in der Sie Deklarationen für die implementierenden Klassen definieren können, Sie können jedoch auch Implementierungen in der abstrakten Klasse selbst definieren.

Zum Beispiel könnte man eine abstrakte NameBase Klasse wie so hat:

public abstract NameBase : EntityBaseDm 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public string FormattedName 
    { 
     get 
     { 
      return LastName + ", " + FirstName; 
     } 
    } 
} 

Ihre Klassen dann erbt die abstrakte Klasse Umsetzung:

public class StudentDm : NameBase { 
} 

public class ProviderDm : NameBase { 
} 

Hinweis, brauchen Sie nicht den Namen zu definieren, Eigenschaften in einer dieser Klassen, aber sie stehen weiterhin zur Verwendung zur Verfügung:

var student = new StudentDm(); 
student.FirstName = "John"; 
student.LastName = "Smith"; 

var fullName = student.FormattedName; // returns Smith, John 
+0

Es sollte angemerkt werden, dass er eine abstrakte Klasse * oder * nicht wollen * möchte. Es ist durchaus möglich, dass er die 'NameBase' für etwas verwenden/instanziieren möchte und eine abstrakte Klasse dies nicht zulassen würde. – Mikanikal

+0

@Mikanikal gibt es nichts in seiner Frage zu sagen, und eine abstrakte Klasse erfüllt seine Anforderungen. Beachten Sie auch, dass die Methode als "virtuell" gekennzeichnet werden kann, sodass sie in der implementierenden Klasse überschrieben werden kann. – Steve

+0

es gibt nichts in seinem Beitrag, um das Gegenteil vorzuschlagen. Deshalb habe ich gesagt * darf * oder * darf nicht *. Nur zu versuchen, darauf hinzuweisen, dass "die Antwort eine abstrakte Klasse ist" ist nicht die einzige Antwort und er sollte alle seine Möglichkeiten verstehen. – Mikanikal

0

Sie fragen nach Mehrfachvererbung und das ist mit C# nicht möglich. Ihre Option besteht darin, eine Zwischenklasse zu erstellen, die von EntityBaseDM erbt und nur die gewünschte Methode implementiert. Ihr ProviderDm oder StudentDm würde von IntermediateBaseDM herleiten und mehr Eigenschaften zur Verfügung stellen.

class IntermediateBaseDM : EntityBaseDM 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public string FormattedName 
    { 
     get 
     { 
      return LastName + ", " + FirstName; 
     } 
    } 
} 
3

Bevor Sie weiter, überlegen, was, wenn Sie noch eine andere Methode erstellen passieren, dass einige dieser Objekte teilen sollten, aber andere sollten nicht. Der Versuch, Funktionen durch Vererbung zusammenzubringen, kann plötzlich unordentlich werden. Es funktioniert nicht öfter als es tut.

Sie haben vielleicht die Empfehlung gehört, "Zusammensetzung über Vererbung zu bevorzugen". Im Allgemeinen bedeutet es, dass es besser ist, Dinge zusammenzubringen, die benötigte Funktionen bereitstellen, anstatt zu versuchen, eine Hierarchie zu erreichen, in der die Funktionen, die Sie benötigen, in Basisklassen sind.

Wenn ein "Name" konsistente Funktionalität wie Formatierung benötigt, ist dies ein Fall, um es zu einer eigenen Klasse zu machen.

public class Name 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string FormattedName { get { return LastName + ", " + FirstName; } } 
} 

haben dann eine Eigenschaft auf StudentDm

public Name StudentName { get; set;} 

auch immer Sie es tun, würde ich nicht empfehlen Klassen in einer Hierarchie nur wegen ein paar gemeinsamen Eigenschaften platzieren. Früher oder später (normalerweise eher) kommt etwas, das in einige der vererbten Klassen gehört, aber nicht in andere, und dann wird es kompliziert.

Verwandte Themen