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

ОГЛАВЛЕНИЕ

Атрибуты можно использовать, чтобы предоставить функциональную возможность множественного наследования для классов C#

Введение

Данная статья показывает возможный способ реализовать множественное наследование (MI) внутри кода C#. Этот способ не имеет таких классических проблем MI, как порядок наследования.

Предпосылки

Есть немало способов избежать или преодолеть необходимость использования MI в C#. Но иногда, особенно для маленьких проектов (игры и т.д.), было бы более подходящим использовать его преимущества. Мы надеемся найти более разумный путь, на котором нас не будут беспокоить препятствия, которые собственный код C# помещает на пути множественного наследования.

Мы не рассматриваем множественное наследование как хороший образец программирования вообще. Его нужно использовать, только когда преимущества этой модели перевешивают недостатки.

Класс

Сначала нужно определить изящный родительский класс, который будет обрабатывать всю функциональность, необходимую для реализации MI. Это не очень сложно. Отсутствующее наследование будет компенсировано классом MI attribute.

using System;
using System.Collections.Generic;

namespace CSharpMultipleInheritance
{
    public class Ancestor : MarshalByRefObject
    {

Когда создается класс, унаследованный от класса Ancestor, набор экземпляров его пользовательского класса attribute собирается и сохраняется в словаре. Этот хэш позже будет использоваться для доступа к унаследованным свойствам (методы и т.д.)

private readonly Dictionary<Type, Object> attributes = null;

public Dictionary<Type, Object> Attributes
{
    get { return attributes; }
}

public Ancestor()
{
    attributes = GetAttributes(GetType());
}

private Dictionary<Type, Object> GetAttributes(Type sourceType)
{
    Object[] collection = sourceType.GetCustomAttributes(true);
    Dictionary<Type, Object> result = new Dictionary<Type, Object>();

    foreach (Object attribute in collection)
    {
        Type attributeType = attribute.GetType();

        if (result.ContainsKey(attributeType))
        {
            throw new Exception(string.Format(
            STR_DupliciteAttributeFound, attributeType.Name, sourceType.Name));
        }
        else
        {
            result.Add(attributeType, attribute);
        }
    }

    return result;
}