如何在C#中使用反射修改不存在的字段?及特定代码输出404实现
问题1:如何在C#中使用反射修改不存在的字段
反射只能操作已存在的类型成员(字段、属性等),不存在的字段没有对应的内存结构,无法直接通过反射修改。如果需要给对象动态添加字段并赋值,有两种实用方案:
- 使用
ExpandoObject:它支持动态添加成员,无需反射即可直接赋值,示例代码:dynamic expando = new ExpandoObject(); expando.NewField = "动态添加的字段值"; Console.WriteLine(expando.NewField); - 动态生成类型(借助
System.Reflection.Emit):可以在运行时创建包含目标字段的新类型,再通过反射修改字段值,但这种方式复杂度高,仅适用于特殊场景。
问题2:不修改Mutate方法、不使用unsafe代码,让程序输出404
实现思路
利用C#的字符串驻留池特性:const string编译时会被加入字符串驻留池,后续var nonConst = "000"会直接引用驻留池中的同一个实例。通过反射修改该实例的内部私有字符数组,即可让所有引用该字符串的变量显示修改后的值。
修改后的完整代码
using System.Reflection; const string constStr = "000"; Mutate(constStr); // 反射修改驻留池中"000"的内部字符数组 var stringType = typeof(string); // .NET Core/.NET 5+用"_value",.NET Framework用"m_stringValue" var valueField = stringType.GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic); if (valueField != null) { char[] chars = (char[])valueField.GetValue(constStr); chars[0] = '4'; chars[1] = '0'; chars[2] = '4'; } var nonConst = "000"; Console.WriteLine(nonConst); static void Mutate(string str) { }
说明
这种操作违背了C#字符串不可变的设计原则,可能导致其他依赖"000"的代码出现异常,仅作为技术探讨使用,禁止在生产环境中应用。
内容的提问来源于stack exchange,提问作者Simon Great
相关产品推荐
相关产品推荐

