• 实现.net下的动态代理(续)多对象Mixin


    实现.net下的动态代理 一文使用动态代理实现了 Ducking Typing,解决了文中的第一个问题,下面,向第二个问题进军——mixin。

    一、应用场景

    (1) 假定有一个接口TInterface,一个类B,类C。类B与类C分别实现了部分TInterface:

     1    public interface TInterface
     2    {
     3        String A get; }
     4        String B(int a, int b);
     5    }

     6
     7    public class ClassB
     8    {
     9        public String A
    10        {
    11            get
    12            {
    13                return String.Empty;
    14            }

    15            set
    16            { }
    17        }

    18    }

    19
    20    public class ClassC
    21    {
    22        public String B(int a, int b)
    23        {
    24            return (a + b).ToString();
    25        }

    26    }

    假设b和c分别是B和C的一个实例,通过 TypeTemplate.Create<TInterface>(b,c) 方法将b和c包装一下,即可生成一个TInterface实例:

    1            ClassB b = new ClassB();
    2            ClassC c = new ClassC();
    3            TInterface i2 = TypeTemplate.Create<TInterface>(b, c);
    4

    (2) 通过Mixin,我们还可以在运行时动态替换接口的指定方法或属性:

     1    public interface Human
     2    {
     3        String Heart();
     4        String Lung();
     5        String Name();
     6    }

     7
     8    public class ZhouBapi : Human
     9    {
    10        public String Heart() return "好心"; }
    11        public String Lung() return "好肺"; }
    12        public String Name() return "周扒皮"; }
    13    }

    14
    15    public class Huaidan
    16    {
    17        public String Heart() return "狼心"; }
    18        public String Lung() return "狗肺"; }
    19    }

    20
    21    class Program
    22    {
    23        static void Show(Human body)
    24        {
    25            Console.WriteLine(String.Format("我叫{0},我是{1}{2}", body.Name(), body.Heart(), body.Lung()));
    26        }

    27
    28        static void ShowHuaidan(Human body)
    29        {
    30            Console.WriteLine(String.Format("{0},我看你是{1}{2}", body.Name(), body.Heart(), body.Lung()));
    31        }

    32
    33        static void Main(string[] args)
    34        {
    35            Human zhou = new ZhouBapi();
    36            Console.Write("周扒皮: ");
    37            Show(zhou);
    38            zhou = TypeTemplate.Create<Human>(new Huaidan(), zhou);
    39            Console.Write("人民群众:");
    40            ShowHuaidan(zhou);
    41            Console.Read();
    42        }

    43    }

    输出为:

    周扒皮: 我叫周扒皮,我是好心好肺
    人民群众:周扒皮,我看你是狼心狗肺

    二、实现

    以下是详细实现代码:

    Code

    测试代码:

     1        [TestMethod]
     2        public void TestCreate()
     3        {
     4            ClassA a = new ClassA();
     5            TInterface i1 = TypeTemplate.Create<TInterface, ClassA>(a);
     6            Assert.AreNotEqual(null, i1);
     7            Assert.AreEqual("3", i1.B(12));
     8            Assert.AreEqual(String.Empty, i1.A);
     9
    10            ClassB b = new ClassB();
    11            ClassC c = new ClassC();
    12            TInterface i2 = TypeTemplate.Create<TInterface>(b, c);
    13            Assert.AreNotEqual(null, i2);
    14            Assert.AreEqual("3", i2.B(12));
    15            Assert.AreEqual(String.Empty, i2.A);
    16        }

    17

    三、说明:

    (1)通过上述方法可以很方便的创建对现有实例的Wrapper,使其适应一个新的接口;

    (2)TypeTemplate.Create<TInterface>(params Object[] impleInstances) 排位在前的 impleInstance 的接口方法/属性将掩盖它后面的 impleInstance 的接口方法/属性,这样可以在运行时动态改变接口的行为。

    (3)这种MixIn方案比不上动态语言的MixIn,主要是必须要有一个interface,才能MixIn。如果能将interface也根据被代理的对象的行为动态生成,那就很爽了。怎么实现,是一个问题。

    版权所有,欢迎转载
  • 相关阅读:
    mongodb 配置单实例与双实例
    redis 集群 搭建
    memcached 搭建
    公网yum 源地址
    jdk 安装
    activemq 搭建--集群
    zookeeper 安装
    activemq 安装-单点
    rabbitmq 集群
    python——网络编程
  • 原文地址:https://www.cnblogs.com/xiaotie/p/1381973.html
Copyright © 2020-2023  润新知