C#中只读成员

本文介绍了C#中的只读成员概念,包括只读字段和只读属性。详细解释了实例字段、静态字段、只读实例字段、只读静态字段及常量的区别,并提供了具体的代码示例。

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

只读成员包括只读字段和只读属性。如果不希望在初始化后修改数据成员,就可以把他们变成只读成员。

1、只读字段

介绍:声明时使用 readonly修饰,放在类型前,与 static 可以更换修饰顺序,只能在构造函数中分配值。

区分:实例字段,静态字段,只读实例字段,只读静态字段,常量

public class MyClass
{
	// 实例字段,可以在类的外部改变他的值
	public  int aa = 3;
	// 静态字段,可以通过类名访问,也可以在类外修改
	public  static int dd = 3;
	// 只读实例字段,尽管是公有的,除了本类(注意:只有本类,子类是只读)的构造函数,其他地方只读
	public  readonly int bb = 3;
	// 只读静态字段,只能在静态构造函数中做初始化,其他地方只读
	public  static readonly  int bb1 = 3;
	// 常量(隐式静态的),不能加上static修饰符,在类外可以通过类名访问
	public  const int cc = 3;

	public MyClass()
	{
		// 在构造函数中,可以对只读实例字段进行赋值
		bb = 4;
	}
	static MyClass()
	{
		// 在静态构造函数中,可以对只读静态字段进行赋值
		bb1 = 5;
	}
	
}

变量与常量相关介绍点击打开链接

静态构造函数介绍链接点击打开链接

2、只读属性

介绍:只有get,没有set,只可以读取,只能在构造函数中赋值。

public class Monkey
{
	// 私有字段,表示猴子的腿的数量
	private int num;
	// 只读属性,(只有get,没有set),只允许在构造函数中初始化属性的值
	public int GetNum
	{
		get{return num;}
	}
}



### 修改 C# 中的只读属性 在 C# 中,只读属性通常通过仅提供 `get` 访问器而省略 `set` 访问器来定义[^1]。这意味着外部代码无法直接更改该属性的值。然而,在某些特殊情况下,可以通过反射或其他技术手段强行修改这些只读属性。 #### 使用反射修改只读字段或属性 如果目标是一个真正的只读字段(即带有 `readonly` 关键字修饰的字段),则可以利用反射机制访问并修改它的私有状态。以下是实现这一操作的具体方式: ```csharp using System; using System.Reflection; public class ExampleClass { public readonly int ReadOnlyField = 42; } class Program { static void Main() { var obj = new ExampleClass(); Console.WriteLine($"Before modification: {obj.ReadOnlyField}"); FieldInfo fieldInfo = typeof(ExampleClass).GetField( "ReadOnlyField", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (fieldInfo != null && fieldInfo.IsInitOnly) { RuntimeHelpers.PrepareConstrainedRegions(); // Optional but recommended. object[] args = { 99 }; var method = typeof(FieldInfo).GetMethod("SetValueDirect", BindingFlags.NonPublic | BindingFlags.Instance); method.Invoke(fieldInfo, new object[] { __makeref(obj), args[0] }); Console.WriteLine($"After modification: {obj.ReadOnlyField}"); } } } ``` 上述代码展示了如何通过调用非公开方法 `SetValueDirect` 来绕过正常的保护机制从而改变 `readonly` 字段的值[^4]。 需要注意的是,这种方法依赖于 CLR 的内部细节,并且可能在未来版本中被移除或者行为发生改变。因此不建议将其用于生产环境下的应用程序开发当中。 对于纯属性而言(仅有 getter 方法却没有 setter 方法的情况),除非它背后存在可变的支持成员变量并且能够找到合适的途径去调整那个隐藏起来的状态信息,则一般是没有办法直接对外部不可见的部分做出任何实质性的改动来的[^2]。 另外值得注意的一点是关于不同版本间的兼容性问题。随着.NET Framework 和相应Visual Studio 平台更新迭代不断推进,旧版特性支持可能会有所变化,请参照具体语言版本历史记录确认当前使用的框架是否完全适用所提及的技术方案[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值