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

69 阅读2分钟
        catch(Exception ex){
        }
    }
}

}


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


----------------------------------


## 使用反射得到任意类型


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


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


### 动态创建实例


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



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

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

List ls = CreateElement<List>();


### 通过类名获得类型


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


那么,我们就需要先得到一个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<Thread>>>对象,想用 GetTypeByName("Dictionary<string,Dictionary<int,List<Thread>>>")来尝试一下能否获得Type。嗯,不出预料,返回了一个null


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


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


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


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


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


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


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



    public static Type GetTypeByName(string typename)
    {
        Type t = null;
        string source = typename;
        if (source.IndexOf('<') > 0)
        {
            List<string> lv = new List<string>();
            while (RegexExpand.IsMatch(source, @"<[^<>]+>"))
            {
                lv.Add(RegexExpand.Match(source, @"(?<=<)[^<>]+(?=>)").Value);
                source = RegexExpand.Replace(source, @"<[^<>]+>", "/" + (lv.Count - 1));
            }
            List<Type[]> args = new List<Type[]>();
            for (int i = 0; i < lv.Count; i++)
            {
                List<Type> arg = new List<Type>();
                string[] sp = lv[i].Split(',');
                for (int j = 0; j < sp.Length; j++)
                {
                    string s = sp[j].Trim();
                    if (!string.IsNullOrEmpty(s))
                    {
                        if (RegexExpand.IsMatch(s, @"/\d+$"))
                        {
                            Match m = RegexExpand.Match(s, @"^([^/\s]+)\s*/(\d+)$");
                            if (!m.Success)
                            {
                                throw new Exception("");
                            }
                            Type p = GetTypeByName(m.Groups[1].Value);
                            Type c = p.MakeGenericType(args[Convert.ToInt32(m.Groups[2].Value)]);
                            arg.Add(c);
                        }
                        else
                        {
                            arg.Add(GetTypeByName(s));
                        }
                    }
                }
                args.Add(arg.ToArray());
            }
            Match f = RegexExpand.Match(source, @"^([^/\s]+)\s*/(\d+)$");
            if (!f.Success)
            {
                throw new Exception("");
            }
            Type fp = GetTypeByName(f.Groups[1].Value);
            Type fc = fp.MakeGenericType(args[Convert.ToInt32(f.Groups[2].Value)]);
            return fc;
        }
        else
        {
            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;
    }

得到类型了,创建实例就跟简单了,将之前出现的CreateElement变动一下



public static dynamic CreateElement(string typename){ Type t = GetTypeByName(typename); return t.Assembly.CreateInstance(t.FullName); }




**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f6596610907944e481d44a284d6b4b4e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771856245&x-signature=eQWscZFJuSXFyiToN3anz%2FklFmM%3D)
![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8e66116f40fd4ee3ac1f1c5796ccfe6c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771856245&x-signature=5UAxnCuF6GYSQPQq1YzjEW2j3yI%3D)

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**

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

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