实现.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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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

3

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
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

输出为:
周扒皮: 我叫周扒皮,我是好心好肺
人民群众:周扒皮,我看你是狼心狗肺
人民群众:周扒皮,我看你是狼心狗肺
二、实现
以下是详细实现代码:

测试代码:
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(1, 2));
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(1, 2));
15
Assert.AreEqual(String.Empty, i2.A);
16
}
17

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

三、说明:
(1)通过上述方法可以很方便的创建对现有实例的Wrapper,使其适应一个新的接口;
(2)TypeTemplate.Create<TInterface>(params Object[] impleInstances) 排位在前的 impleInstance 的接口方法/属性将掩盖它后面的 impleInstance 的接口方法/属性,这样可以在运行时动态改变接口的行为。
(3)这种MixIn方案比不上动态语言的MixIn,主要是必须要有一个interface,才能MixIn。如果能将interface也根据被代理的对象的行为动态生成,那就很爽了。怎么实现,是一个问题。
本文xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2009/02/01/1381973.html如需转载请自行联系原作者
xiaotie 集异璧实验室(GEBLAB)