C#中UnsafeAccessor实现访问私有成员
我们在开发时会经常遇到一个类中需要访问另一个类中私有成员的情况,但是.net是不允许直接访问的。UnsafeAccessor
让这种操作成为可能。
使用反射
在.net8之前可以使用反射来实现访问私有成员
1 | public class MyClass |
使用反射来获取私有成员的方式还是比较优雅的,但是性能略差,其实还有两种性能比较高的方式分别是Emit和Expression,但是这两种实现方式实现起来不够优雅,在这里不多介绍,有兴趣可以自行学习。
使用UnsafeAccessor
.net8引入了UnsafeAccessor
类来实现访问私有变量,而且性能极高,和直接访问不相上下。
1 | public class MyClass |
UnsafeAccessor
存在于System.Runtime.CompilerServices
命名空间中,然后必须定义一个staic extern ref
,返回类型为私有变量的类型,参数就是实例类型。在方法上面我们需要添加一个UnsafeAccessor
特性,这个特性有一个参数UnsafeAccessorKind
,这个参数表示我们要访问的是什么类型的私有成员,比如字段、属性、方法等等,这里我们要访问的是字段,所以我们传入的是UnsafeAccessorKind.Field
,然后我们还需要指定要访问的字段的名称,这里我们要访问的是_value
字段,所以我们传入的是Name = "_value"
,这样我们就可以通过UnsafeAccessor
来访问私有成员了
而且因为返回ref的引用,可以直接修改私有字段
1 | var a = new MyClass(); |
目前UnsafeAccessor的局限性:
- 不支持泛型,也许会在后续版本更新
1 | //错误用法 |
- 不支持私有类型如
private class MyClass
- 不支持静态类
C#中UnsafeAccessor实现访问私有成员