С# Множественное наследование

В настоящее время я изучаю С# с ASP.NET MVC 4 с Code First Approach. Im Visual Basic Developer, и теперь я хочу запустить С#. И теперь я столкнулся с ситуацией, когда мне нужно управлять множественным наследованием. Но это невозможно в классе I. Итак, как мне управлять этими классами, у меня есть:

//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; }
}

То, что я хочу сделать, одобрено, ApprovedDate и ApprovedUserId также распространено. Я хочу указать эти свойства, например:

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

И, хотите использовать как:

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

И я не могу поместить эти вещи внутри PERSON. Потому что я должен использовать это для других классов, но это не Person.

Затем, как мне достичь этого...

Пожалуйста, дайте мне пример для вышеуказанной ситуации.

Пожалуйста, помогите. И, Большое спасибо вам в Advance.

Ответ 1

Одним из возможных решений могло бы стать изменение вашей иерархии:

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

public class Student : PersonWithApprove {
}

public class Faculty : PersonWithApprove {
}

Или вы можете создать интерфейс:

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

public class Student : Person, IApprove {
}

Вы также можете оставить класс Approve как таковой и иметь классы с свойством этого типа:

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

Ответ 2

Это хороший случай, ИМХО, чтобы использовать интерфейсы здесь, что-то вроде этого:

  // 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
  }

Ответ 3

Короткий ответ

Рассмотрим вместо этого использование интерфейсов, которые допускают множественное наследование и могут быть объявлены с помощью ключевого слова interface.

Длинный ответ

Наследование из нескольких базовых классов в С# является незаконным. Классы могут иметь только 1 базовый класс, тогда как они могут реализовать любое количество интерфейсов. Есть несколько причин для этого, но в основном это сводится к тому, что множественное наследование вводит гораздо большую сложность в иерархию классов.

Интерфейсы используются для объявления группы общих функций (методов и свойств), которые должны быть реализованы классом.

Чтобы изменить существующий код на использование интерфейсов (вместо множественного наследования), вы можете сделать следующее:

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
}

Этот подход абстрагирует реализацию интерфейса IApprove и, подобно множественному наследованию, позволяет пользователю работать с объектами, которые реализуют IApprove, но их конкретный тип неизвестен (или не имеет значения).

Для получения дополнительной информации об использовании интерфейсов в С# обратитесь к:

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

Ответ 4

Вы можете использовать композитный шаблон

    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

Рассмотрим следующий пример: он использует два интерфейса:

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();
    }

}

Ответ 6

В базовом примере с использованием шаблона Decorator:

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;
        }
    }
}

Демо:

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