2013-08-26 18 views
11

Obecnie im studiuje C# z ASP.NET MVC 4 z Code First Approach. Im Visual Basic Developer, a teraz chcę uruchomić C#. I teraz znalazłem się w sytuacji, w której muszę zarządzać wieloma dziedziczeniami. Ale nie jest to możliwe w przypadku klasy i. Tak, jak należy zarządzać tych klas mam:C# Dziedziczenie wielokrotne

//I have the Following Person Class which Hold Common Properties 
//and a Type of Person e.g : Student, Faculty, Administrative 
public class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Type { get; set; } 
} 


//This is my Student Class, which is Derived from Person 
public class Student:Person 
{ 
    public DateTime DateOfBirth { get; set; } 
    public DateTime EnrollmentDate { get; set; } 
    public string Remarks { get; set; } 


    public bool Approved { get; set; } 
    public DateTime ApprovedDate { get; set; } 
    public int ApprovedUserId { get; set; } 
} 


//This is my Faculty Class, which is also Derived from Person 
public class Faculty : Person 
{ 
    public DateTime HiredDate { get; set; } 


    public bool Approved { get; set; } 
    public DateTime ApprovedDate { get; set; } 
    public int ApprovedUserId { get; set; } 
} 

Co chcę zrobić jest zatwierdzony, ApprovedDate i ApprovedUserId także wspólne. Chcę określić te właściwości, takie jak:

public class Approve { 
    public bool Approved { get; set; } 
    public DateTime ApprovedDate { get; set; } 
    public int ApprovedUserId { get; set; } 
} 

I chcesz używać jak:

public class Student:Person,Approve 
{ 
    public DateTime DateOfBirth { get; set; } 
    public DateTime EnrollmentDate { get; set; } 
    public string Remarks { get; set; } 
} 

I nie mogę umieścić te rzeczy wewnątrz OSOBY. Ponieważ, muszę użyć tego do innych klas, ale nie są to Osoby.

Potem, jak mogę to osiągnąć ...

proszę dać mi przykład dla powyższej sytuacji.

Proszę o pomoc. I, bardzo dziękuję z góry.

+3

W języku C#, można dziedziczyć jedną klasę i wdrożenia wielu interfejsów i trzeba umieścić klasę pierwszą. –

+0

Spróbuj użyć interfejsów – wudzik

+0

Lub użyj Zatwierdź jako właściwość w klasie ucznia –

Odpowiedz

22

Możliwym rozwiązaniem byłoby zmodyfikować swoją hierarchię:

public class PersonWithApprove : Person { // TODO: replace with non disgusting name 
    public bool Approved { get; set; } 
    // etc... 
} 

public class Student : PersonWithApprove { 
} 

public class Faculty : PersonWithApprove { 
} 

Lub można utworzyć interfejs:

public interface IApprove { 
    bool Approved { get; set; } 
    // etc 
} 

public class Student : Person, IApprove { 
} 

Można również opuścić klasę Approve jako taką i mieć klasy z właściwością tego t yp:

public class Student : Person { 
    Approve _approve = new Approve(); 
    public Approve Approve { 
     get { return _approve; } 
    } 
} 
2

Można użyć Composite wzór

public class Student:Person 
    { 
     public Approve App { get; set; } 
     public DateTime DateOfBirth { get; set; } 
     public DateTime EnrollmentDate { get; set; } 
     public string Remarks { get; set; } 
    } 
5

To dobra sprawa, IMHO, aby korzystać z interfejsów tu coś takiego:

// Interfaces: 

    // General person 
    public interface IPerson { 
    int Id { get; set; } 
    string FirstName { get; set; } 
    string LastName { get; set; } 
    string Type { get; set; } 
    } 

    // Approvable person 
    public interface IApprovable { 
    bool Approved { get; set; } 
    DateTime ApprovedDate { get; set; } 
    int ApprovedUserId { get; set; } 
    } 

    // Student is a IPerson + IApprovable 
    public interface IStudent: IPerson, IApprovable { 
    DateTime DateOfBirth { get; set; } 
    DateTime EnrollmentDate { get; set; } 
    } 

    // So classes will be 

    public class Approve: IApprovable { 
    ... //TODO: Implement IApprovable interface here 
    } 

    public class Faculty: IPerson, IApprovable { 
    public DateTime HiredDate { get; set; } 

    ... //TODO: Implement IPerson interface here 
    ... //TODO: Implement IApprovable interface here 
    } 

    public class Student: IStudent { 
    public string Remarks { get; set; } 

    ... //TODO: Implement IStudent interface here 
    } 
5

Krótka odpowiedź

Zastanów się nad wykorzystaniem interfejsów zamiast, które pozwalają na wielokrotne dziedziczenie i może być zadeklarowane za pomocą słowa kluczowego interface.

długa odpowiedź

Dziedziczenie z wielu klas bazowych w C# jest nielegalne. Klasy mogą mieć tylko 1 klasę bazową, podczas gdy mogą implementować dowolną liczbę interfejsów. Istnieje several reasons for this, ale w większości sprowadza się to do tego, że dziedziczenie wielokrotne wprowadza o wiele więcej złożoności w hierarchię klas.

Interfejsy służą do deklarowania grupy wspólnych funkcji (metod i właściwości), które muszą być implementowane przez klasę.

Aby zmodyfikować istniejący kod do używania interfejsów (zamiast wielu dziedziczenie), można wykonać następujące czynności:

public interface IApprove // Defines a set of functionality that a class must implement. 
{ 
    // All these properties must be inherited as public when implemented. 
    bool Approved { get; set; } // Property declaration. 
    DateTime ApprovedDate { get; set; } 
    int ApprovedUserId { get; set; } 
} 

public class Student : Person, IApprove 
{ 
    public DateTime DateOfBirth { get; set; } 
    public DateTime EnrollmentDate { get; set; } 
    public string Remarks { get; set; } 

    #region IApprove Implementation 

    private bool _approved; // Private variable that is accessed through the 'Approved' property of the 'IApprove' interface. 
    public bool Approved // Defines 'Approved' inherited from IApprove 
    { 
     get { return _approved; } 
     set { _approved = value; } 
    } 

    private DateTime _approvedDate; 
    public DateTime ApprovedDate // Defines 'ApprovedDate' inherited from IApprove. 
    { 
     get { return _approvedDate; } 
     set { _approvedDate = value; } 
    } 

    private int _approvedUserId; 
    public int IApprove.ApprovedUserId // Alternative syntax to define an interfaces property. 
    { 
     get { return _approvedUserId; } 
     set { _approvedUserId = value; } 
    } 

    #endregion 
} 

Podejście to abstrahuje się wdrożenie interfejsu IApprove i jak wielokrotne dziedziczenie, pozwala użytkownik działa na obiektach, które implementują IApprove, ale ich konkretny typ jest nieznany (lub nieistotny).

Aby uzyskać więcej informacji na temat wykorzystania interfejsów w C# dotyczą:

http://msdn.microsoft.com/en-us/library/87d83y5b.aspx

2

Rozważmy następujący przykład, wykorzystuje dwa interfejsy:

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


//////// 
//////// 
/// Multiple Inheritance With Interfaces 

public interface Interface1 
{ 
    void func1(); 
    void fun(); 
} 

public interface Interface2 
{ 
    void func2(); 
    void fun(); 
} 

public class MyTestBaseClass : Interface1, Interface2 
{ 
    void Interface1.func1() 
    { 
     Console.WriteLine("From MyInterface1 Function()"); 
     return; 
    } 


    void Interface2.func2() 
    { 
     Console.WriteLine("From MyInterface2 Function()"); 
     return; 
    } 

    void Interface1.fun() 
    { 
     Console.WriteLine("fun1()"); 
    } 

    void Interface2.fun() 
    { 
     Console.WriteLine("fun2()"); 
    } 


    public static void Main() 
    { 
     MyTestBaseClass myclass = new MyTestBaseClass(); 
     ((Interface1)myclass).func1(); 
     ((Interface2)myclass).func2(); 
    } 

} 
0

Niektóre podstawowy przykład stosując Dekorator wzór:

public class Class1 
{ 
    public void Method1() 
    { 
     Console.write($"Class1: Method1, MyInt: {MyInt}"); 
    } 

    public int MyInt { get; set; } 
} 

public class Class2 
{ 
    public void Method2() 
    { 
     Console.write($"Class2: Method2, MyInt: {MyInt}");  
    } 

    public int MyInt { get; set; } 
} 

public class MultipleClass 
{ 
    private Class1 class1 = new Class1(); 
    private Class2 class2 = new Class2(); 

    public void Method1() 
    { 
     class1.Method1(); 
    } 
    public void Method2() 
    { 
     class2.Method2(); 
    } 

    private int _myInt; 
    public int MyInt 
    { 
     get { return this._myInt; } 
     set 
     { 
      this._myInt = value; 
      class1.MyInt = value; 
      class2.MyInt = value; 
     } 
    } 
} 

Demo:

MultipleClass multipleClass = new MultipleClass(); 
multipleClass.Method1(); //OUTPUT: Class1: Method1, MyInt: 1 
multipleClass.Method2(); //OUTPUT: Class2: Method2, MyInt: 1 
multipleClass.MyInt = 1; 
Powiązane problemy