【问题标题】:How do people get mixin-style re-use in C#?人们如何在 C# 中获得 mixin 风格的重用?
【发布时间】:2010-09-29 13:38:56
【问题描述】:

我来自 C++ 背景,我可以使用模板混合来编写引用 FinalClass 的代码,这是一个传入的模板参数。这允许可重用​​函数“混合”到任何派生类,只需继承自 ReusableMixin,模板参数为 MyFinalClass。这一切都被内联到类中,所以就好像我刚刚写了一个可以做所有事情的大类——即非常快!由于 mixins 可以链接,我可以将各种行为(和状态)混合到一个对象中。

如果有人想了解该技术,请询问。我的问题是,我怎样才能在 C# 中获得这样的重用?注意:C# 泛型不允许从泛型参数继承。

【问题讨论】:

  • 顺便说一下,你可以有一个通用继承。我经常使用它。
  • 嗯?你是说我可以写 class foo : T {} 我不这么认为

标签: c# c++ generics code-reuse template-mixins


【解决方案1】:

您可以使用接口和扩展方法。例如:

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 继承来使用 mixins。请记住,在 (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();
    }
}

HTH。

【讨论】:

    【解决方案2】:

    在 C# 中,最接近 C++ 风格的 mixins 是将 mixins 添加为类的字段并向类添加一堆转发方法:

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

    如果您只想导入 mixin 的功能和状态,这通常就足够了。 mixin 当然可以随心所欲地实现,包括(私有)字段、属性、方法等。

    如果你的类还需要用 mixins 表达“is-a”关系,那么你需要执行以下操作:

    interface IMixin1
    {
        int Property1 { get; set; }
    }
    
    interface IMixin2
    {
        void Do2();
    }
    
    class MyClass : IMixin1, IMixin2
    {
        // implementation same as before
    }
    

    (这也是 C# 中模拟多重继承的标准方式。)

    当然,mixin 接口和 mixin 类都可以是泛型的,例如使用最派生的类参数或其他。

    【讨论】:

    • 但是如果你想混入状态呢?
    • 我已经相应地修改了答案,HTH。
    • 嗯...看起来还可以。 mixin 的最佳用途之一是为您实现一个接口,因此不得不手动编写每个方法是相当痛苦的。我不知道您是否说服我更喜欢 C#,但您感谢您的回答!
    【解决方案3】:

    在 C# 中,您可以使用“partial”关键字来指示您的类在多个源文件中实现。然后,您可以使用一个小模板工具来自动生成其他源代码文件,其中包含您要在类中注入的方法。

    可以使用 Visual Studio 中包含的 T4 模板工具来执行此操作,但可以使用更简单的方法。查看我自己的模板引擎:http://myxin.codeplex.com/

    【讨论】:

      【解决方案4】:

      http://remix.codeplex.com 上查看 .net 的混音库

      这个库为 .NET 带来了 mixins

      【讨论】:

        【解决方案5】:

        扩展方法对您的场景有帮助吗?

        【讨论】:

        • 我不这么认为,我不必指定我正在扩展的类,所以我不能将它们应用于一大堆类......我没有不过,你对他们了解很多,是吗?
        • 扩展方法的问题在于它只是语法糖。该方法只能访问类的公共(或内部,如果在同一程序集中)接口。此外,只有记住包含扩展方法的命名空间时,它才会对类的用户可见。
        猜你喜欢
        • 2017-09-09
        • 2011-10-28
        • 1970-01-01
        • 2011-01-08
        • 2012-04-03
        • 1970-01-01
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多