C# 根据typename字符串,创建任意类型的对象(含泛型)_c# 根据类名创建对象

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

动态创建实例

通过类名获得类型

分析如何获得泛型类型

实现根据类名,获得泛型类型

小计


认识一下反射

在c#中,反射时个很好用的东西,可以通过反射动态创建一个实例,且实例类型不唯一

一个很简单的例子,来了解下反射可以做什么

Type t = typeof(Form);
dynamic frm = t.Assembly.CreateInstance(t.FullName);
// 以上内容完全等同于
dynamic frm = new Form();


Type t = typeof(List<string>);
dynamic lst = t.Assembly.CreateInstance(t.FullName);
// 以上内容完全等同于
dynamic lst = new List<string>();

看起来好像反射没什么用,因为他现在完成的,我们都可以自己完成啊

那么,换个场景,有一个函数,传递进来一个object对象,如果对象存在Run方法,就运行该方法,如果不存在Run,但存在Start,则运行Start方法,再不行,就按照Begin、Do等方法依次向后查找,这个时候,如果用switch来枚举object可能的类型不是不可以,但是这样会造成后期需要经常维护此处代码,所以用反射来调用

public void RefInvokeStart(object obj){
    Type t = obj.GetType();
    string[] methods = new string[]{"Run","Start","Begin","Do"};
    for(int i=0;i<methods.Length;i++){
        MethodInfo method = t.GetMethod(methods[i]);
        if (method!=null){
            try{
                method.Invoke(null,new object[]{obj,null});
                return;
            }
            catch(Exception ex){
            }
        }
    }
}

以上是反射的简单例子,现在翻篇了。


使用反射得到任意类型

在实际应用中,有时候我们在开发的过程中,脑子会突然抽筋,非常想不开的想用一个方法,来实现不同的需求,嗯,泛型就是为此准备的,但实际工作时,我们只知道对象类型,甚至只知道类型名称,连类型全名(含命名空间路径的类型名称)都不知道,就要创建相应类型的实例

嗯。。。。其实文盲脑子也这么抽过,虽然后来回头看的时候,总觉得不需要这么处理,还有其他方法。。。。但脑子抽的时候可没想过这些 T_T

动态创建实例

先来个根据已知对象动态创建实例的方法

public static T CreateElement<T>(){
    Type t = typeof(T);
    return (T)t.Assembly.CreateInstance(t.FullName);
}

// 很简单的就可以创建,基本等同于new

List<string> ls = CreateElement<List<string>>();

通过类名获得类型

然后,我们只知道类型的名字,不知道全名,也没有确定类型。。。

那么,我们就需要先得到一个Type才可以

        public static Type GetTypeByName(string typename)
        {
            Type t = null;
            string source = typename;
                try
                {
                    t = Type.GetType(source);
                    if (t != null)
                    {
                        return t;
                    }
                    Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
                    foreach (Assembly ass in assembly)
                    {
                        t = ass.GetType(source);
                        if (t != null)
                        {
                            return t;
                        }
                        Type[] ts = ass.GetTypes();
                        foreach (Type st in ts)
                        {
                            if (RegexExpand.IsMatch(st.FullName, @"\." + RegexExpand.FormatRegExp(source) + @"(`?\d+)?$"))
                            {
                                return st;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {

                }
            return t;
        }

简单来讲,就是根据typename字符串,获得Type类型数据,根据当前项目所调用的所有类库中,查找相同,或者包含我们写的这个名称的类型,并返回,比如 Type t1 = GetTypeByName(“string”);GetTypeByName(“Form”);GetTypeByName(“Thread”);

分析如何获得泛型类型

嗯,简单的名称对照类型就这么简单。再然后,就是重点了,有很多类型是支持泛型的,这些东西能通过反射得到类型吗?

比如,我现在想创建一个 Dictionary<string,Dictionary<int,List>>对象,想用 GetTypeByName(“Dictionary<string,Dictionary<int,List>>”)来尝试一下能否获得Type。嗯,不出预料,返回了一个null

因为我们所有对比的内容,都是单一类型,而传递进去的这个字符串,却是一个多类型组合的多泛型结构。。。还tmd带嵌套的

但是,也不是不能实现,整理下思路:

首先,最内层一对<>里肯定不包含其他类型了,这个是已经确定的;

其次,我们肯定不能写一个多泛型的对象,里面多个泛型都还是支持泛型的,比如绝对不会出现Dictionary<List,List>这样的两个泛型都是支持泛型的类型。。有一个就够了

再次,我们根据<>,从里到外获得所有类型字符串,并按顺序记录下来,然后将内层的对象作为参数传递给外层的对象,通过MakeGenericType方法来创建支持泛型的对象

实现根据类名,获得泛型类型

那么,思路有了,接下来就来实现这个方法吧

        public static Type GetTypeByName(string typename)
        {
            Type t = null;
            string source = typename;


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/78afa660a91712ba05df9297c16ceb22.png)
![img](https://img-blog.csdnimg.cn/img_convert/2dcfd1799affdf7a769f820accd89806.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

存中...(img-GjGZhtnl-1715675580712)]

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值