首页 > 编程语言 >C# 反射

C# 反射

时间:2023-03-11 11:22:05浏览次数:32  
标签:反射 Invoke 获取 C# Person person Type

反射是一种在运行时动态获取程序类型信息的技术,它可以用来查找和操作程序中的类型、成员、属性和方法等。

·以下是一个简单的利用反射查找、创建对象、调用方法、获取/修改属性、字段的示例代码:

using System;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        // 通过反射查找类型
        Type type = Type.GetType("Demo.Person");

        // 通过反射创建对象
        object person = Activator.CreateInstance(type);

        // 通过反射调用方法
        MethodInfo methodInfo = type.GetMethod("SayHello");
        methodInfo.Invoke(person, null);

        // 通过反射获取属性
        PropertyInfo propertyInfo = type.GetProperty("Name");
        Console.WriteLine("Name: {0}", propertyInfo.GetValue(person));

        // 通过反射修改属性
        propertyInfo.SetValue(person, "Tom", null);
        Console.WriteLine("Name: {0}", propertyInfo.GetValue(person));

        // 通过反射获取字段
        FieldInfo fieldInfo = type.GetField("Age");
        Console.WriteLine("Age: {0}", fieldInfo.GetValue(person));

        // 通过反射修改字段
        fieldInfo.SetValue(person, 20);
        Console.WriteLine("Age: {0}", fieldInfo.GetValue(person));
    }
}

class Person
{
    public string Name { get; set; }
    public int Age;

    public void SayHello()
    {
        Console.WriteLine("Hello, my name is {0}.", Name);
    }
}


在这个示例中,我们通过反射查找了一个名为Demo.Person的类型,并创建了一个该类型的对象。然后,我们使用反射获取了该对象的SayHello方法,并通过Invoke方法调用了该方法。接着,我们使用反射获取了该对象的Name属性,并获取了该属性的值。然后,我们通过反射修改了该对象的Name属性的值,并再次获取了该属性的值。最后,我们使用反射获取了该对象的Age字段,并获取了该字段的值。然后,我们通过反射修改了该对象的Age字段的值,并再次获取了该字段的值。

·使用反射调用构造器,可以通过以下步骤实现:

通过Type.GetType方法或者typeof关键字获取目标类型的Type对象。例如,获取Demo.Person类型的Type对象可以使用以下代码:Type type = Type.GetType("Demo.Person"); 或者 Type type = typeof(Demo.Person);

使用Type.GetConstructor方法获取目标类型的构造器。该方法接受一个Type[]参数,用于指定构造器的参数类型。如果要调用无参数构造器,可以使用Type.GetConstructor(Type.EmptyTypes)方法。例如,获取Demo.Person类型的无参数构造器可以使用以下代码:ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);

使用ConstructorInfo.Invoke方法调用构造器。该方法接受一个object[]参数,用于指定构造器的参数值。如果调用无参数构造器,该参数可以传入null或者空数组。例如,调用Demo.Person类型的无参数构造器可以使用以下代码:object person = constructor.Invoke(null);
完整示例代码如下:

using System;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        // 获取类型
        Type type = typeof(Demo.Person);

        // 获取构造器
        ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);

        // 调用构造器
        object person = constructor.Invoke(null);

        // 调用对象方法
        MethodInfo methodInfo = type.GetMethod("SayHello");
        methodInfo.Invoke(person, null);
    }
}

class Person
{
    public void SayHello()
    {
        Console.WriteLine("Hello, I'm a new person.");
    }
}

在这个示例中,我们使用Type.GetConstructor(new Type[] { typeof(string), typeof(int) })获取了Demo.Person类型的接受string和int类型参数的构造器,并使用ConstructorInfo.Invoke(new object[] { "Tom", 20 })方法调用该构造器,创建了一个带有Name和Age属性的Demo.Person类型的对象。

·Activator.CreateInstance和constructor.Invoke都可以用于创建对象,但它们的实现方式有所不同。

Activator.CreateInstance是一个静态方法,它使用指定的类型名、程序集名、参数等信息来创建一个实例。它可以自动选择适当的构造函数进行创建,并且支持泛型类型的创建。使用Activator.CreateInstance可以避免手动获取构造函数的过程,让创建对象的过程更加简便。但是,由于其通过字符串来指定类型名和程序集名,因此需要在编译时指定完整的类型名和程序集名,不太方便动态获取类型。

constructor.Invoke则是使用反射获取到一个构造函数后,通过Invoke方法来调用构造函数,创建一个对象。与Activator.CreateInstance相比,使用constructor.Invoke需要手动获取构造函数,需要明确指定构造函数的参数,因此相对来说更加复杂。但是,它可以在运行时动态获取类型和构造函数,更加灵活。

总的来说,Activator.CreateInstance适用于已知类型名和程序集名的情况,可以让创建对象更加简便;而constructor.Invoke适用于需要动态获取类型和构造函数的情况,更加灵活。

标签:反射,Invoke,获取,C#,Person,person,Type
From: https://www.cnblogs.com/johnyang/p/17205535.html

相关文章

  • C#中的弱引用
    弱引用保持的是一个GC“不可见”的引用,是指弱引用不会增加对象的引用计数,也不会阻止垃圾回收器对该对象进行回收。因此,弱引用的目标对象可以被垃圾回收器回收,而弱引用本身......
  • AC.844 走迷宫
     #include<iostream>#include<queue>#include<utility>//pair容器的头文件#include<cstring>//memsetusingnamespacestd;constintN=1e2+7;intn,m;intg[......
  • 记一次archlinux+dwm的安装
    记一次Archlinux+dwm简单安装联网rfkillunblockalldhcpcdpingwww.baidu.com-n同步时间timedatectlset-ntptrue换源vim/etc/pacman.d/mirrorlistServer=......
  • [CSS] 胶囊按钮与border-radius
    胶囊按钮高度固定以前在写这种形状的按钮的时候,我一般是写了一个固定高度,然后border-radius设置为高度的一半:.pill-button{width:auto;min-width:128px;......
  • db + mysql vs oracle
    smysql与oracle的几点区别序号mysqloracle备注1.组函数用法规则mysql中组函数在select语句中可以随意使用oracle中如果查询语句中有组函数,那其他列名必须是......
  • vscode cn_blog测试
    vscodecn_blog测试1.编辑文本,插入图片2.插入代码print('Hello!cn_blog')vim~/.bashrc......
  • 跟艾文学编程《零基础入门学Python》PyCharm 安装
    作者:艾文,计算机硕士学位,企业内训讲师和金牌面试官,公司资深算法专家,现就职BAT一线大厂。学习目标PyCharm下载PyCharm工具的使用利用PyCharm工具开发第一个应用程序PyChar......
  • ES008-Elasticsearch+hbase整合
    1:设计索引库的settings信息的mappings信息,并把这些配置信息保存到一个配置文件中。1.1viarticles.json{"settings":{"number_of_shards":3,"nu......
  • ES007-Elasticsearch中文分词集成
    1、elasticsearch官方只提供smartcn这个中文分词插件,效果不是很好2、引入分词器前命令行下测试curl'http://localhost:9200/jf/_analyze?pretty=true'-d'{......
  • 浙大版《C语言程序设计(第3版)》题目集 习题5-1 符号函数
    本题要求实现符号函数sign(x)。函数接口定义:intsign(intx);其中​​x​​是用户传入的整型参数。符号函数的定义为:若​​x​​大于0,​​sign(x)​​ = 1;若​​x​​等......