Как люди получают повторное использование в стиле mixin в C #? - PullRequest
4 голосов
/ 05 января 2009

Я пришел из C ++ фона, где я могу использовать шаблонные миксины для написания кода, который ссылается на FinalClass, который является передаваемым параметром шаблона. Это позволяет многократно использовать функции, которые «смешиваются» с любым производным классом, просто наследование от ReusableMixin с параметром шаблона MyFinalClass. Все это вписывается в класс, как будто я просто написал большой класс, который сделал все - то есть очень быстро! Поскольку миксины могут соединяться, я могу смешивать все виды поведения (и состояния) в одном объекте.

Если кто-то хочет получить разъяснения по технике, пожалуйста, спросите. Мой вопрос, как я могу получить такое повторное использование в C #? Примечание. Обобщения C # не позволяют наследовать от обобщенного параметра.

Ответы [ 5 ]

12 голосов
/ 05 января 2009

Вы можете использовать интерфейсы и методы расширения. Например:

public interface MDoSomething // Where M is akin to I
{
     // Don't really need any implementation
}

public static class MDoSomethingImplementation
{
     public static string DoSomething(this MDoSomething @this, string bar) { /* TODO */ }
}

Теперь вы можете использовать миксины, наследуя их от MDoSomething. Помните, что использование методов расширения внутри (this) класса требует спецификатора this. Например:

public class MixedIn : MDoSomething
{
    public string DoSomethingGreat(string greatness)
    {
         // NB: this is used here.
         return this.DoSomething(greatness) + " is great.";
    }
}

public class Program
{
    public static void Main()
    {
        MixedIn m = new MixedIn();
        Console.WriteLine(m.DoSomething("SO"));
        Console.WriteLine(m.DoSomethingGreat("SO"));
        Console.ReadLine();
    }
}

НТН.

4 голосов
/ 05 января 2009

В C # ближе всего к миксинам в стиле C ++ добавляются миксины в качестве полей класса и добавляется куча методов пересылки в класс:

public class MyClass
{
    private readonly Mixin1 mixin1 = new Mixin1();
    private readonly Mixin2 mixin2 = new Mixin2();

    public int Property1
    {
        get { return this.mixin1.Property1; }
        set { this.mixin1.Property1 = value; }
    }

    public void Do1()
    {
        this.mixin2.Do2();
    }
}

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

Если вашему классу также необходимо выразить отношения "is-a" с миксинами, вам нужно сделать следующее:

interface IMixin1
{
    int Property1 { get; set; }
}

interface IMixin2
{
    void Do2();
}

class MyClass : IMixin1, IMixin2
{
    // implementation same as before
}

(Это также стандартный способ эмуляции множественного наследования в C #.)

Конечно, интерфейсы mixin, а также классы mixin могут быть обобщенными, например, с наиболее производным параметром класса или чем-то еще.

2 голосов
/ 10 января 2010

В C # вы можете использовать ключевое слово «part», чтобы указать, что ваш класс реализован в нескольких исходных файлах. Затем вы можете использовать небольшой инструмент для создания шаблонов, чтобы автоматически генерировать дополнительные файлы исходного кода, которые содержат методы, которые вы хотите внедрить в свой класс.

Для этого можно использовать шаблонизатор T4, включенный в Visual Studio, но можно использовать более упрощенный подход. Смотрите мой собственный шаблонизатор: http://myxin.codeplex.com/

1 голос
/ 26 апреля 2011

Проверьте библиотеку ремиксов для .net на http://remix.codeplex.com

Эта библиотека переносит миксины в .NET

0 голосов
/ 05 января 2009

Методы расширения помогут в вашем сценарии?

...