C#反射

本文介绍了如何使用C#的Type类进行反射操作,包括获取类的属性、字段,并通过GetValue和SetValue方法进行读写操作。示例代码展示了如何访问静态和实例字段,并对不同访问级别的字段进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ClassType  ClassName=new ClassType();//一个实例化的类,类型是ClassType  ,类名为ClassName
Type type = ClassName.GetType();       //得到Type类型
FieldInfo[] info = type.GetFields(); //得到字段数组
foreach (FieldInfo i in info ) //遍历此数组
{
     object obj = i.GetValue(ClassName); //变量值
     string name = i.Name; //变量名


Type 类

C#中通过 Type类可以访问任意数据类型信息。
1.获取给定类型的Type引用有3种方式:
   a.使用typeof运算符,如Type t = typeof(int);
   b.使用GetType()方法,如int i;Type t = i.GetType();
   c.使用 Type类的静态方法GetType(),如Type t =Type.GetType("System.Double");
2.Type的属性:
   Name:数据类型名;
   FullName:数据类型的完全限定名,包括命名空间;
   Namespace:数据类型的命名空间;
   BaseType:直接基本类型;
   UnderlyingSystemType:映射类型;
3.Type的方法:
   GetMethod():返回一个方法的信息;
   GetMethods():返回所有方法的信息。


PropertyInfo[] ps = type.GetProperties();//得到属性数组

PropertyInfo propertyInfo = type.GetProperty("Property1"); //获取指定名称的属性

propertyInfo.GetValue(ClassName, null); //获取属性值

propertyInfo.SetValue(ClassName, value, null); //给对应属性赋值



Type.GetFields();//只获取public字段,静态public字段和实例public字段都获取

Type.GetFields(BindingFlags);//获取BindingFlags标记的字段

BindingFlags//由于BindingFlags的枚举值按位定义,如果使用多于两个BindingFlags可以用位运算|

BindingFlags.Static 和BindingFlags.Instance中至少要有一个

枚举值 成员名称 描述
由 XNA Framework 提供支持   512 CreateInstance 指定“反射”应该创建指定类型的实例。 调用与给定参数匹配的构造函数。 忽略提供的成员名。 如果未指定查找类型,将应用 (Instance |Public)。 调用类型初始值设定项是不可能的。
由 XNA Framework 提供支持受 可移植类库 支持  2 DeclaredOnly 指定只应考虑在所提供类型的层次结构级别上声明的成员。 不考虑继承成员。
由 XNA Framework 提供支持   0 Default 不指定绑定标志。
由 XNA Framework 提供支持受 可移植类库 支持 65536 ExactBinding 指定提供参数的类型必须与对应形参的类型完全匹配。 如果调用方提供一个非空 Binder 对象,则“反射”将引发异常,因为这意味着调用方正在提供的 BindToXXX 实现将选取适当的方法。

“反射”建立通用类型系统的可访问规则模型。 例如,如果调用方在相同的程序集内,则它不需要内部成员的特殊权限。 否则,调用方需要ReflectionPermission 这与保护成员、私有成员等成员的查找是一致的。

一般原则是 ChangeType 应该只执行拓宽强制,后者从不丢失数据。 扩展强制的一个例子是将 32 位有符号整数值强制为 64 位有符号整数值。这与窄缩强制不同,后者可能丢失数据。 窄缩强制的一个例子是将 64 位有符号整数强制为 32 位有符号整数。

默认联编程序忽略此标志,而自定义联编程序可以实现此标志的语义。

由 XNA Framework 提供支持受 可移植类库 支持  64 FlattenHierarchy 指定应返回层次结构上的公共静态成员和受保护的静态成员。 不返回继承类中的私有静态成员。 静态成员包括字段、方法、事件和属性。 不返回嵌套类型。
由 XNA Framework 提供支持   1024 GetField 指定应返回指定字段的值。
由 XNA Framework 提供支持   4096 GetProperty 指定应返回指定属性的值。
由 XNA Framework 提供支持受 可移植类库 支持  1 IgnoreCase 指定当绑定时不应考虑成员名的大小写。
由 XNA Framework 提供支持 16777216 IgnoreReturn 在 COM 互操作中用于指定可以忽略成员的返回值。
由 XNA Framework 提供支持受 可移植类库 支持  4 Instance 指定实例成员将包括在搜索中。
由 XNA Framework 提供支持   256 InvokeMethod 指定要调用一个方法。 它不能是构造函数或类型初始值设定项。
由 XNA Framework 提供支持受 可移植类库 支持  32 NonPublic 指定非公共成员将包括在搜索中。包括internal,protected,private
由 XNA Framework 提供支持受 可移植类库 支持  262144 OptionalParamBinding 返回其参数计数与提供参数的数目匹配的成员集。 此绑定标志用于所带参数具有默认值的方法和带变量参数 (varargs) 的方法。 此标志应只与Type.InvokeMember 一起使用。

具有默认值的参数仅用在省略尾部参数的调用中。 它们必须是最后的参数。

由 XNA Framework 提供支持受 可移植类库 支持  16 Public 指定公共成员将包括在搜索中。只有public
由 XNA Framework 提供支持   16384 PutDispProperty 指定应调用 COM 对象的 PROPPUT 成员。 PROPPUT 指定使用值的属性设置函数。 如果属性同时具有 PROPPUT 和 PROPPUTREF,而且需要区分调用哪一个,请使用 PutDispProperty
由 XNA Framework 提供支持   32768 PutRefDispProperty 指定应调用 COM 对象的 PROPPUTREF 成员。 PROPPUTREF 指定使用引用而不是值的属性设置函数。 如果属性同时具有 PROPPUT 和PROPPUTREF,而且需要区分调用哪一个,请使用PutRefDispProperty
由 XNA Framework 提供支持   2048 SetField 指定应设置指定字段的值。
由 XNA Framework 提供支持   8192 SetProperty 指定应设置指定属性的值。 对于 COM 属性,指定此绑定标志与指定PutDispProperty 和 PutRefDispProperty 是等效的。
由 XNA Framework 提供支持受 可移植类库 支持  8 Static 指定静态成员将包括在搜索中。
由 XNA Framework 提供支持   131072 SuppressChangeType 未实现。

FieldInfo.SetValue(Object obj,Object value);

参数
obj
类型: System.Object
将设置其字段值的对象。
value
类型: System.Object
分配给字段的值。
当obj是null的时候只能对静态字段赋值,对非静态字段赋值会报错

当obj是实例的时候可以对任意字段赋值

例子

using UnityEngine;
using System.Collections;
using System;
using System.Reflection;


public class FanSheText : MonoBehaviour {
void Start () {
        FanShe myInstance = new FanShe();
        Type t = typeof(FanShe);
        FieldInfo[] sharedFields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        Debug.LogError("静态开始");
        foreach (FieldInfo f in sharedFields)
        {
            try
            {
                string newValue = f.GetValue(null) + " -存储成功-";
                
                f.SetValue(null, newValue);


                print(String.Format("The value of Shared field {0} is: {1}\n",f.Name,f.GetValue(null)));
            }
            catch
            {
                print(String.Format("The value of Shared field {0} is not accessible.\n", f.Name));
            }
        }
        Debug.LogError("静态结束");


        FieldInfo[] instanceFields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        Debug.LogError("实例开始");
        foreach (FieldInfo f in instanceFields)
        {
            try
            {
                // Append a marker to the old value.
                string newValue = f.GetValue(myInstance) + " -存储成功-";


                f.SetValue(myInstance, newValue);


                print(String.Format("The value of insktance field {0} is: {1}\n", f.Name, f.GetValue(myInstance)));
            }
            catch
            {


                print(String.Format("The value of instance field {0} is not accessible.\n", f.Name));
            }
        }
        Debug.LogError("实例结束");
}
}


public class FanShe
{
    public static string SA = "A public shared field.";
    internal static string SB = "A friend shared field.";
    protected static string SC = "A protected shared field.";
    private static string SD = "A private shared field.";
    private static string se = "";
    public static string SE
    {
        get
        {
            return se;
        }
        set
        {
            se = value;
        }
    }


    public string A = "A public instance field.";
    internal string B = "A friend instance field.";
    protected string C = "A protected instance field.";
    private string D = "A private instance field.";
    private string e = "";
    public string E
    {
        get
        {
            return e;
        }
        set
        {
            e = value;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值