zoukankan      html  css  js  c++  java
  • C# 中反射获取某类的子类和根据类型名动态创建对象

    有时候,为了快速批量处理已经实现某个基类或者某个接口的子类,需要通过反射的方式获取到他们的类类型(Type),然后再通过

    1
    Activator.CreateInstance(objType);

    或者

    1
    Assembly.Load(path).CreateInstance(typeName);

    或者

    1
    Assembly.LoadFile(filePath).CreateInstance(typeName);

    创建对象实例。

    以下通过一个简单的示例来展示:
    1,获取当前程序集中的全部类型;
    2,判断某一类型是否是继承与另一类型;
    3,根据类型名动态创建对象。

    目前还有个疑问,不知道谁能解答:
    1,如何判断某个类是否实现了某个接口,目前只能先 new 一个对象,然后再 用 is 判断。

    1
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;
    using System.Diagnostics;
     
    namespace com.hetaoos
    {
     
        class Test
        {
            public Test()
            {
                var types = Assembly.GetExecutingAssembly().GetTypes();
                var baseType = typeof(BaseProcessor);
                List<BaseProcessor> processors = new List<BaseProcessor>();
                foreach (var t in types)
                {
                    var tmp = t.BaseType;
                    while (tmp != null)
                    {
                        if (tmp == baseType)
                        {
                            BaseProcessor obj = MethodMaker.CreateObject(t.FullName) as BaseProcessor;
                            if (obj != null)
                            {
                                processors.Add(obj);
                            }
                            break;
                        }
                        else
                        {
                            tmp = tmp.BaseType;
                        }
                    }
                }
     
                Debug.Print("Processor Count:{0}", processors.Count);
                foreach (var p in processors)
                {
                    Debug.Print("{0} :{1}", p, p.Calc(2, 5));
                }
            }
        }
     
        public class MethodMaker
        {
     
            /// <summary>
            /// 创建对象(当前程序集)
            /// </summary>
            /// <param name="typeName">类型名</param>
            /// <returns>创建的对象,失败返回 null</returns>
            public static object CreateObject(string typeName)
            {
                object obj = null;
                try
                {
                    Type objType = Type.GetType(typeName, true);
                    obj = Activator.CreateInstance(objType);
                }
                catch (Exception ex)
                {
                    Debug.Write(ex);
                }
                return obj;
            }
     
            /// <summary>
            /// 创建对象(外部程序集)
            /// </summary>
            /// <param name="path"></param>
            /// <param name="typeName">类型名</param>
            /// <returns>创建的对象,失败返回 null</returns>
            public static object CreateObject(string path, string typeName)
            {
                object obj = null;
                try
                {
     
                    obj = Assembly.Load(path).CreateInstance(typeName);
                }
                catch (Exception ex)
                {
                    Debug.Write(ex);
                }
     
                return obj;
            }
        }
     
        public abstract class BaseProcessor
        {
            public abstract int Calc(int a, int b);
        }
     
        public class Adder : BaseProcessor
        {
            public override int Calc(int a, int b)
            {
                return a + b;
            }
        }
     
        public class Multiplier : BaseProcessor
        {
            public override int Calc(int a, int b)
            {
                return a * b;
            }
        }
    }

    输出结果为:

    1
    2
    3
    Processor Count:2
    com.hetaoos.Adder   :7
    com.hetaoos.Multiplier  :10

    PS:
    判断某个类是否继承自某个接口、类的方法:

    1
    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
    public static bool IsParent(Type test, Type parent)
    {
        if (test == null || parent == null || test == parent || test.BaseType == null)
        {
            return false;
        }
        if (parent.IsInterface)
        {
            foreach (var t in test.GetInterfaces())
            {
                if (t == parent)
                {
                    return true;
                }
            }
        }
        else
        {
            do
            {
                if (test.BaseType == parent)
                {
                    return true;
                }
                test = test.BaseType;
            } while (test != null);
     
        }
        return false;
    }
  • 相关阅读:
    C#语法相比其它语言比较独特的地方
    Git源码管理工具使用
    2018年第九届蓝桥杯题目(C/C++B组)汇总
    Unity插件系列之二维码
    在本机使用虚拟机安装一个linux系统,并搭建ftp服务器
    用UE4蓝图制作FPS_零基础学虚幻4第二季
    【坦克大战】Unity3D多人在线游戏(泰课的坦克大战--旋转的螺丝钉)
    Drag(拖拽)和Move(移动)两个脚本
    解决:Word在试图打开文件时遇到错误
    2018年的一些记录,共勉
  • 原文地址:https://www.cnblogs.com/yelanggu/p/5196161.html
Copyright © 2011-2022 走看看