C# 反射无法获取get set中属性

本文介绍了一种使用.NET反射API来获取对象属性信息的方法,并对比了不同方式获取属性的区别,特别是如何通过反射访问get和set方法。

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

先前写法

 //定义一个获取反射内容的方法 保存时用到

 //定义一个获取反射内容的方法 保存时用到
        public void getreflectioninfo(Object o)
        {
            //Assembly.Load 方法参数为 命名空间名称
            Assembly myAssembly = Assembly.Load(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace);
            Type[] typearr = myAssembly.GetTypes();//获取类型
            Type type = myAssembly.GetType(o.GetType().FullName);

            //获取类型的字段信息
            FieldInfo[] myfields = type.GetFields();
            //获取属性信息 非get set 可获取到
            //PropertyInfo[] myproperties = type.GetProperties();
            //针对属性get set提供的反射
            PropertyInfo[] pi = o.GetType().GetProperties();
            //对数据进行清空
            this.xmlElementMap.Clear();
            foreach (PropertyInfo pro in pi)
            {
                object val  = pro.GetValue(o, null);
                //如果值为null处理为""
                if (val == null)
                {
                    val = "";
                }
                XmlElementMap.Add(pro.Name, val);
                //对于nodeId的处理
                if (pro.Name.ToLower() == "id")
                {
                    this.XmlnodeId = pro.GetValue(o, null).ToString();
                }
            }

            this.ParentNodeName = type.Name + "s";
            this.XmlNodeName = type.Name;
        }


其中

  //获取属性信息 非get set 可获取到            //PropertyInfo[] myproperties = type.GetProperties();

红色部分为先前无法访问get set的代码

//针对属性get set提供的反射            PropertyInfo[] pi = o.GetType().GetProperties();

绿色部分为修改后可以访问get set 的代码


 

 

### C# 反射获取无 `get` 或 `set` 访问器的属性C# 中,如果一个类中的属性仅定义了部分访问器(即只有 `get` 而没有 `set`,反之亦然),则可以通过反射机制来处理这些属性。对于只读属性(仅有 `get` 的情况),尝试使用反射设置其值将会引发异常[^1]。 然而,在某些情况下,可能需要操作那些未公开修改接口的私有或受保护成员。此时可以利用反射绕过常规的语言约束: #### 使用反射获取和设置私有字段 即使某个属性本身不可写入,通常该属性背后存在一个支持存储数据的私有字段。下面展示了一个例子,说明如何通过反射访问并更改此类隐藏字段的内容: ```csharp using System; using System.Reflection; public class Person { private string _name; // 私有的字段 public string Name => _name; // 只读属性, 没有提供setter } class Program { static void Main() { var person = new Person(); Type type = typeof(Person); FieldInfo fieldInfo = type.GetField("_name", BindingFlags.NonPublic | BindingFlags.Instance); Console.WriteLine($"Before setting value: {person.Name}"); if (fieldInfo != null && fieldInfo.IsInitOnly == false) { fieldInfo.SetValue(person, "John"); MethodInfo getterMethod = type.GetProperty("Name").GetGetMethod(); object result = getterMethod.Invoke(person, null); Console.WriteLine($"After setting value via reflection: {result}"); } } } ``` 这段代码展示了如何定位到 `_name` 字段并通过它间接改变 `Name` 属性的实际内容。需要注意的是这种方法依赖于具体实现细节,并不是推荐的做法,因为它破坏了封装原则并且可能导致难以调试的行为。 另外值得注意的一点是在 .NET Core/.NET 5+ 版本中,默认行为已经调整为不自动包装由反射调用所抛出的原始异常至更高级别的 `TargetInvocationException` 中,除非特别指定了相反选项[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值