C# 4.0 与C#4.0混合

C# 4.0 与C#4.0混合,c#-4.0,mixins,C# 4.0,Mixins,我看到了关于是否可以在C#中创建mixin的各种问题,它们通常被引导到codeplex上的re-mix项目。然而,我不知道我是否喜欢“完整接口”的概念。理想情况下,我会这样扩展一个类: [Taggable] public class MyClass { .... } 通过简单地添加标记接口,我可以通过某种对象工厂创建MyClass类型的对象。返回的实例将在MyClass中定义所有成员,以及通过添加标记属性(如标记集合)提供的所有成员。使用C#4.0

我看到了关于是否可以在C#中创建mixin的各种问题,它们通常被引导到codeplex上的re-mix项目。然而,我不知道我是否喜欢“完整接口”的概念。理想情况下,我会这样扩展一个类:

    [Taggable]
    public class MyClass
    {
       ....
    }

通过简单地添加标记接口,我可以通过某种对象工厂创建MyClass类型的对象。返回的实例将在MyClass中定义所有成员,以及通过添加标记属性(如标记集合)提供的所有成员。使用C#4.0(动态关键字)似乎很容易做到这一点。重新混合项目使用C#3.5。有没有人能在不改变类本身的情况下通过C#4.0扩展对象?谢谢。

您可以在C#4.0中创建类似mixin的构造,而无需使用动态,在接口上使用扩展方法并使用类来存储状态。看看这个想法

下面是一个例子:

public interface MNamed { 
  // required members go here
}
public static class MNamedCode {
  // provided methods go here, as extension methods to MNamed

  // to maintain state:
  private class State { 
    // public fields or properties for the desired state
    public string Name;
  }
  private static readonly ConditionalWeakTable<MNamed, State>
    _stateTable = new ConditionalWeakTable<MNamed, State>();

  // to access the state:
  public static string GetName(this MNamed self) {
    return _stateTable.GetOrCreateValue(self).Name;
  }
  public static void SetName(this MNamed self, string value) {
    _stateTable.GetOrCreateValue(self).Name = value;
  }
}

使用属性的问题在于不能将泛型参数从类流到mixin。您可以使用标记接口来实现这一点。

您可以创建一个
DynamicObject
,以责任链的方式将它接收到的调用转发到一个目标列表(请注意,多态分派也可以这样工作-从最派生的类向上):

您可以将它们“混合”在一起:

dynamic blend = new Composition(new MyClass(), new MyOtherClass());
blend.MyClassMethod();
blend.MyOtherClassMethod();
您还可以扩展动态对象以使用类的属性或其他类型的注释来查找混合。例如,给定此注释界面:

public interface Uses<M> where M : new() { }
并创建如下“混合”:

class Order : MNamed { // you can list other mixins here...
  ...
}

...

var o = new Order();
o.SetName("My awesome order");

...

var name = o.GetName();
class MyMixin {
  public void MyMixinMethod() {
    Console.WriteLine("MyMixin::Method");
  }
}

class MyClass : Uses<MyMixin> {
  public void MyClassMethod() {
    Console.WriteLine("MyClass::Method");
  }
}

...

dynamic blend = new MixinComposition(new MyClass());
blend.MyClassMethod();
blend.MyMixinMethod();
类MyMixin{ public void MyMixinMethod(){ WriteLine(“MyMixin::Method”); } } 类MyClass:使用{ public void MyClassMethod(){ WriteLine(“MyClass::Method”); } } ... 动态混合=新的混合分解(新的MyClass()); blend.MyClassMethod(); blend.MyMixinMethod();
我一直在为C#开发一个开源的Mixin框架。它利用分部类和代码生成器将Mixin类连接到目标:

//Mixin - Class that contains members that should be injected into other classes.
public class Mixin
{
   // This method should be in several class
   public void Method(){ }
}

//Target (Note: That it is partial) - Add members from Mixin
[pMixn(Target = typeof(Mixin)]
public partial class Target{}


//Example of using Target
public class Consumer
{
    public void Example()
    {
        var target = new Target();

        // can call mixed in method
        target.Method();

        // can implicitly convert Target to Mixin
        Mixin m = new Target();
        m.Method();
   }
}

我知道这是一个老话题,但我也想介绍一个我目前正在从事的开源项目:

它是一个基于Roslyn的Visual Studio 2015重构扩展,通过生成所需的委托代码,为C#添加了mixin支持

例如,假设您有以下要重用的mixin代码:

// mixin class with the code you want to reuse
public class NameMixin
{
    public string Name { get; set; }
    public void DoSomething() { }
}
以及要包含mixin的给定子类:

// child class where the mixin should be included
public class Person
{
    // reference to the mixin
    private NameMixin _name = new NameMixin();
}
如果在
NameMixin\u name
字段上执行mixinSharp重构步骤,扩展将自动添加将mixin包含在类中所需的所有粘合代码:

public class Person
{
  // reference to the mixin
  private NameMixin _name = new NameMixin();

  public string Name
  {
      get { return _name.Name; }
      set { _name.Name = value; }
  }
  public void DoSomething() => _name.DoSomething();
}
除此之外,mixinSharp还有一些额外的特性,如mixin实例的构造函数注入、用mixin实现接口等等


源代码可以在上找到,二进制文件(编译的Visual Studio扩展)可以在中找到。

我在2008年的一个项目中使用依赖项注入样式库,该库允许我们使用内部域特定语言(DSL)定义应用程序的设计(在代码中)

该库允许我们定义系统,并将这些系统与其他系统组合起来。系统表示在一个范围内实现接口的一组对象。系统/子系统可以选择向父作用域公开接口

这样做的结果是,混合器是免费的。您只需将实现行为切片的类添加到系统定义中,并将其接口公开给父范围。这个系统现在有这种行为

您也可以使用现代依赖注入框架来实现这一点

我们正在使用NDI()


注:我在2008年写过NDI

也许是部分课程?扩展方法?通过使用扩展方法,我将编写更明确的代码,将MyClass与标记相关的代码结合起来(当然,除了标记属性之外)。我不想和他们两个结婚,真是太棒了。为什么选票这么少?没有多重继承的语言使得编写混合变得非常困难。这是.NET语言和Java的一大缺点。非常好的博客帖子!这种方法很好,但不允许从mixin中多态地改变方法。因此,您的另一个答案更加强大(有趣的是,您可以添加两个答案…+1个有趣的框架)。我很久以前也开始了。好主意。您认为XML和JSON序列化程序可以处理混合吗?有些人在遇到问题时会认为“我知道,我将使用动态类型”。现在他们动态地重新分派问题并转换为解决方案,实现了编程天堂。
// mixin class with the code you want to reuse
public class NameMixin
{
    public string Name { get; set; }
    public void DoSomething() { }
}
// child class where the mixin should be included
public class Person
{
    // reference to the mixin
    private NameMixin _name = new NameMixin();
}
public class Person
{
  // reference to the mixin
  private NameMixin _name = new NameMixin();

  public string Name
  {
      get { return _name.Name; }
      set { _name.Name = value; }
  }
  public void DoSomething() => _name.DoSomething();
}