栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C#中的反射

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#中的反射

一:什么是反射

C#编写的程序会编译成一个程序集(.DLL或.exe),其中会包含元数据、编译代码和资源,通过反射可以获取到程序集中的信息
通俗来讲,反射就是我们在只知道一个对象的外部而不了解内部结构的情况下,可以知道这个对象的内部实现


二:反射的优缺点

首先在编译中分为动态编译和静态编译,静态编译是在编译中确定类型,绑定对象,而动态编译是在运行中确定类型,绑定对象
反射的优点就是可以动态创建对象、绑定对象,提高了程序的灵活性和扩展性,但反射是一种解释操作,在性能上不如静态编译快


三:通过Type类获取程序集、模块、类的相关信息

——Type类是一个抽象类,因此不能用他去实例化对象
——object类中定义了一个GetType方法,因此所有类都可以使用GetType()获取到某一个对象所属类的Type对象
——通过Type对象可以获取到类中字段、属性、方法、构造函数等信息

using System;

class MainClass
{
    public static void Main(string[] args)
    {
        //1.通过对象获取到这个对象所属类的Type对象
        TestClass c = new TestClass();
        Type t = c.GetType();

        //2.通过Type类中的静态方法GetType获取到类的Type对象
        //Type t = Type.GetType("TestClass");

        //3.通过typeof关键字获取到类的Type对象
        //Type t = typeof(TestClass);

        Console.WriteLine(t.Name);//获取类名(不带命名空间)
        Console.WriteLine(t.FullName);//获取类名(带命名空间)
        Console.WriteLine(t.Assembly);//获取程序集
        Console.WriteLine(t.BaseType);//获取基类类型

        Console.WriteLine("----------获取类中字段");
        var fields = t.GetFields();
        foreach (var temp in fields)
        {
            Console.WriteLine(temp.Name);
        }

        Console.WriteLine("----------获取类中属性");
        var properties = t.GetProperties();
        foreach (var temp in properties)
        {
            Console.WriteLine(temp.Name);
        }

        Console.WriteLine("----------获取类中方法");
        var methods = t.GetMethods();
        foreach (var temp in methods)
        {
            Console.WriteLine(temp.Name);
        }

        Console.WriteLine("----------获取类中成员");
        var members = t.GetMembers();
        foreach (var temp in members)
        {
            Console.WriteLine(temp.Name);
        }

        Console.WriteLine("----------获取类中嵌套类");
        var nesteds = t.GetNestedTypes();
        foreach (var temp in nesteds)
        {
            Console.WriteLine(temp.Name);
        }

        Console.WriteLine("----------获取类中构造函数");
        var constructors = t.GetConstructors();
        foreach (var temp in constructors)
        {
            Console.WriteLine(temp.Name);
        }
    }
}

public class TestClass
{
    public string str;
    public int num { get; set; }
    public void Fun()
    {

    }
    public class TestNestedClass
    {

    }
}

得到一个Type类型对象有三种方法:object.GetType()、Type.GetType()、typeof()
使用object.GetType()必须先创建一个实例,而后两种不需要创建实例,但使用typeof运算符仍然需要知道类型的编译时信息,Type.GetType()静态方法不需要知道类型的编译时信息,所以是首选方法


四:创建实例:性能上要比new差

——通过Activator创建实例

using System;

class MainClass
{
    public static void Main(string[] args)
    {
        object c = Activator.CreateInstance(typeof(TestClass), "hello world");
        Console.WriteLine(((TestClass)c).str);
    }
}

public class TestClass
{
    public string str;
    public TestClass(string str)
    {
        this.str = str;
    }
}

——通过构造函数创建实例

using System;

class MainClass
{
    public static void Main(string[] args)
    {
        Type t = typeof(TestClass);
        Type[] paramTypes = new Type[1] { typeof(string) };
        var info = t.GetConstructor(paramTypes);
        object[] param = new object[1] { "hello world" };
        var o = info.Invoke(param);

        Console.WriteLine(((TestClass)o).str);
    }
}

public class TestClass
{
    public string str;
    public TestClass(string str)
    {
        this.str = str;
    }
}

五:反射赋值
using System;
using System.Reflection;

class MainClass
{
    public static void Main(string[] args)
    {
        var data = Activator.CreateInstance(Type.GetType("TestClass"));
        var info = data.GetType().GetField("str");
        info.SetValue(data, "hello world");
        Console.WriteLine(info.GetValue(data));
    }
}

public class TestClass
{
    public string str;
}

六:调用类中的方法

——调用类中的方法

using System;
using System.Reflection;

class MainClass
{
    public static void Main(string[] args)
    {
        var data = Activator.CreateInstance(Type.GetType("TestClass"));
        var m1 = data.GetType().GetMethod("TestMethod1");
        var m2 = data.GetType().GetMethod("TestMethod2");
        m1.Invoke(data, null);
        m2.Invoke(data, new object[] { 100});
    }
}

public class TestClass
{
    public void TestMethod1()
    {
        Console.WriteLine("this is TestMethod1");
    }

    public void TestMethod2(int i)
    {
        Console.WriteLine("this is TestMethod" + i);
    }
}

——调用类中其他类的方法
例如调用一个类中List的Add方法

using System;
using System.Reflection;
using System.Collections.Generic;

class MainClass
{
    public static void Main(string[] args)
    {
        var data = Activator.CreateInstance(Type.GetType("TestClass"));
        var fi = data.GetType().GetField("list");
        var list = Activator.CreateInstance(fi.FieldType);
        var mi = list.GetType().GetMethod("Add");
        var pi = list.GetType().GetProperty("Count");
        mi.Invoke(list, new object[] { 1 });
        mi.Invoke(list, new object[] { 2 });

        Console.WriteLine(pi.GetValue(list));
    }
}

public class TestClass
{
    public List list = new List();
}


 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/908537.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号