天天看点

对《以非泛型方式调用泛型方法》一文的探讨

(一)简化

Kanas.Net 对比的5种方案中,1、2、5 三种方案均需要在编译时指定所使用的类型,因此并未解决问题。方案3性能较低,方案4是有效方案:

·定义泛型委托; 

·定义非泛型接口; 

·实现这个接口; 

·通过泛型委托获取非泛型接口的实现。

感觉方案4将问题复杂化了,这里采用委托用处不大,平添加许多复杂性。

我先前错误认为.net中的范型方法是在运行时才实例化的,装配脑袋 指出是在编译期实例化的,用reflector查看代码,正如装配脑袋所言,范型方法是在编译器实例化。因此,要解决以非范型方式调用范型方法的关键就在于在运行期产生指定类型范型方法。Kanas.Net 的方案4既是这个策略:

(1)申明一个非范型接口,用来持有运行期生成的方法,供后期调用;

(2)采用一个范型类,继承非范型接口

(3)一个方法,能够根据指定的类型名称,创建相应的范型类。

采用这种策略,更简洁的实现是引入helper:

 1

对《以非泛型方式调用泛型方法》一文的探讨

    public interface IServerClassHelper

 2

对《以非泛型方式调用泛型方法》一文的探讨

    {

 3

对《以非泛型方式调用泛型方法》一文的探讨

        void InvokeAdd(object obj, object list);

 4

对《以非泛型方式调用泛型方法》一文的探讨

    }

 5

对《以非泛型方式调用泛型方法》一文的探讨

 6

对《以非泛型方式调用泛型方法》一文的探讨

    public class ServerClass

 7

对《以非泛型方式调用泛型方法》一文的探讨

 8

对《以非泛型方式调用泛型方法》一文的探讨

        public void Add<T>(T obj, ICollection<T> c)

 9

对《以非泛型方式调用泛型方法》一文的探讨

        {

10

对《以非泛型方式调用泛型方法》一文的探讨

            c.Add(obj);

11

对《以非泛型方式调用泛型方法》一文的探讨

        }

12

对《以非泛型方式调用泛型方法》一文的探讨

13

对《以非泛型方式调用泛型方法》一文的探讨

        public IServerClassHelper CreateHelper(Type T)

14

对《以非泛型方式调用泛型方法》一文的探讨

15

对《以非泛型方式调用泛型方法》一文的探讨

            Type helperType = typeof(ServerClassHelper<>).MakeGenericType(T);

16

对《以非泛型方式调用泛型方法》一文的探讨

            IServerClassHelper helper = Activator.CreateInstance(helperType, this) as IServerClassHelper;

17

对《以非泛型方式调用泛型方法》一文的探讨

            return helper;

18

对《以非泛型方式调用泛型方法》一文的探讨

19

对《以非泛型方式调用泛型方法》一文的探讨

20

对《以非泛型方式调用泛型方法》一文的探讨

        private sealed class ServerClassHelper<T> : IServerClassHelper

21

对《以非泛型方式调用泛型方法》一文的探讨

22

对《以非泛型方式调用泛型方法》一文的探讨

            private ServerClass m_server;

23

对《以非泛型方式调用泛型方法》一文的探讨

24

对《以非泛型方式调用泛型方法》一文的探讨

            public ServerClassHelper(ServerClass server)

25

对《以非泛型方式调用泛型方法》一文的探讨

            {

26

对《以非泛型方式调用泛型方法》一文的探讨

                m_server = server;

27

对《以非泛型方式调用泛型方法》一文的探讨

            }

28

对《以非泛型方式调用泛型方法》一文的探讨

29

对《以非泛型方式调用泛型方法》一文的探讨

            public void InvokeAdd(object obj, object list)

30

对《以非泛型方式调用泛型方法》一文的探讨

31

对《以非泛型方式调用泛型方法》一文的探讨

                m_server.Add<T>((T)obj, (ICollection<T>)list);

32

对《以非泛型方式调用泛型方法》一文的探讨

33

对《以非泛型方式调用泛型方法》一文的探讨

34

对《以非泛型方式调用泛型方法》一文的探讨

使用:

1

对《以非泛型方式调用泛型方法》一文的探讨

            ClientClassA a = new ClientClassA();

2

对《以非泛型方式调用泛型方法》一文的探讨

            ICollection<ClientClassA> ca = new List<ClientClassA>();

3

对《以非泛型方式调用泛型方法》一文的探讨

            String TypeString = "GenericMethodTest.ClientClassA";

4

对《以非泛型方式调用泛型方法》一文的探讨

            IServerClassHelper helper = server.CreateHelper(Type.GetType(TypeString));

5

对《以非泛型方式调用泛型方法》一文的探讨

            helper.InvokeAdd(a, ca);

性能测试:

1 : 2.09

(二)改进

上面方案使用起来还是比较复杂,首先需要获得一个helper,然后调用helper的相应方法。还是不够直接。继续改进吧,改进成<以非泛型方式调用泛型方法>一文开始所述接口:

Add(Type type, Object obj, Object c)。

以下是代码:

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

        private static ICollection<IServerClassHelper> m_helpers = new List<IServerClassHelper>();

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

        public void Add(Type type, Object obj, Object c)

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

            GetHelper(type).InvokeAdd(obj, c);

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

        private IServerClassHelper GetHelper(Type T)

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

            foreach(IServerClassHelper h in m_helpers)

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

                if (h.Equals(T)) return h;

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

            IServerClassHelper helper = CreateHelper(T);

对《以非泛型方式调用泛型方法》一文的探讨

            m_helpers.Add(helper);

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

        private IServerClassHelper CreateHelper(Type T) 

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

            Type clientType = typeof(ServerClassHelper<>).MakeGenericType(T);

对《以非泛型方式调用泛型方法》一文的探讨

            IServerClassHelper helper = Activator.CreateInstance(clientType, this, T) as IServerClassHelper;

对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨
对《以非泛型方式调用泛型方法》一文的探讨

        private interface IServerClassHelper : IEquatable<Type>

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2007/02/07/643947.html如需转载请自行联系原作者

xiaotie 集异璧实验室(GEBLAB)

继续阅读