当前位置:网站首页>C# 可以利用反射给只读属性赋值吗?
C# 可以利用反射给只读属性赋值吗?
2022-07-26 06:34:00 【51CTO】
结论:可以
验证demo如下:
using
System;
using
System.
Collections.
Generic;
using
System.
ComponentModel;
using
System.
Data;
using
System.
Drawing;
using
System.
Linq;
using
System.
Text;
using
System.
Windows.
Forms;
namespace
IconTest
{
public
partial
class
Form2 :
Form
{
public
Form2()
{
InitializeComponent();
ReflectTest
rt
=
new
ReflectTest();
rt.
GetType().
GetProperty(
"ID").
SetValue(
rt,
"Guid",
null);
MessageBox.
Show(
rt.
ID);
}
}
public
class
ReflectTest
{
private
string
id;
[
ReadOnly(
true)]
public
string
ID
{
get
{
return
id;
}
set
{
id
=
value;
}
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
运行winform程序输出:

小注:
TypeDescriptor.GetProperties用来setvalue这没有作用:
那么为什么TypeDescriptor.GetProperties用来setvalue没有效果呢?
将上面的代码拆成如下两句:
单点跟踪进去,可以发现:

在获取到PropertyDescriptor这个抽象类的实例后,在调用SetValue方法的时候,是从其子类ReflectPropertyDescriptor调用的。


而具体的实现是在子类:ReflectPropertyDescriptor中,从微软源码中找到ReflectPropertyDescriptor及SetValue
public
override
void
SetValue(
object
component,
object
value) {
#if
DEBUG
if (
PropDescUsageSwitch.
TraceVerbose) {
string
compName
=
"(null)";
string
valName
=
"(null)";
if (
component
!=
null)
compName
=
component.
ToString();
if (
value
!=
null)
valName
=
value.
ToString();
Debug.
WriteLine(
"["
+
Name
+
"]: SetValue("
+
compName
+
", "
+
valName
+
")");
}
#endif
if (
component
!=
null) {
ISite
site
=
GetSite(
component);
IComponentChangeService
changeService
=
null;
object
oldValue
=
null;
object
invokee
=
GetInvocationTarget(
componentClass,
component);
Debug.
Assert(
!
IsReadOnly,
"SetValue attempted on read-only property ["
+
Name
+
"]");
if (
!
IsReadOnly) {
// Announce that we are about to change this component
//
if (
site
!=
null) {
changeService
= (
IComponentChangeService)
site.
GetService(
typeof(
IComponentChangeService));
Debug.
Assert(
!
CompModSwitches.
CommonDesignerServices.
Enabled
||
changeService
!=
null,
"IComponentChangeService not found");
}
// Make sure that it is ok to send the onchange events
//
if (
changeService
!=
null) {
oldValue
=
SecurityUtils.
MethodInfoInvoke(
GetMethodValue,
invokee, (
object[])
null);
try {
changeService.
OnComponentChanging(
component,
this);
}
catch (
CheckoutException
coEx) {
if (
coEx
==
CheckoutException.
Canceled) {
return;
}
throw
coEx;
}
}
try {
try {
SecurityUtils.
MethodInfoInvoke(
SetMethodValue,
invokee,
new
object[] {
value });
OnValueChanged(
invokee,
EventArgs.
Empty);
}
catch (
Exception
t) {
// Give ourselves a chance to unwind properly before rethrowing the exception.
//
value
=
oldValue;
// If there was a problem setting the controls property then we get:
// ArgumentException (from properties set method)
// ==> Becomes inner exception of TargetInvocationException
// ==> caught here
if (
t
is
TargetInvocationException
&&
t.
InnerException
!=
null) {
// Propagate the original exception up
throw
t.
InnerException;
}
else {
throw
t;
}
}
}
finally {
// Now notify the change service that the change was successful.
//
if (
changeService
!=
null) {
changeService.
OnComponentChanged(
component,
this,
oldValue,
value);
}
}
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
从代码中可以看出来,只读属性直接被跳过去了。。。。。。
那么PropertyInfo有没有什么限制呢?
PropertyInfo调用的SetValue如下所示:

在微软开源的代码中可以找到其具体实现如下:
[
DebuggerStepThroughAttribute]
[
Diagnostics.
DebuggerHidden]
#if
!
FEATURE_CORECLR
[
TargetedPatchingOptOut(
"Performance critical to inline across NGen image boundaries")]
#endif
public
override
void
SetValue(
Object
obj,
Object
value,
Object[]
index)
{
SetValue(
obj,
value,
BindingFlags.
Public
|
BindingFlags.
NonPublic
|
BindingFlags.
Instance
|
BindingFlags.
Static,
null,
index,
null);
}
[
DebuggerStepThroughAttribute]
[
Diagnostics.
DebuggerHidden]
public
override
void
SetValue(
Object
obj,
Object
value,
BindingFlags
invokeAttr,
Binder
binder,
Object[]
index,
CultureInfo
culture)
{
MethodInfo
m
=
GetSetMethod(
true);
if (
m
==
null)
throw
new
ArgumentException(
System.
Environment.
GetResourceString(
"Arg_SetMethNotFnd"));
Object[]
args
=
null;
if (
index
!=
null)
{
args
=
new
Object[
index.
Length
+
1];
for(
int
i
=
0;
i
<
index.
Length;
i
++)
args[
i]
=
index[
i];
args[
index.
Length]
=
value;
}
else
{
args
=
new
Object[
1];
args[
0]
=
value;
}
m.
Invoke(
obj,
invokeAttr,
binder,
args,
culture);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
暂时没有看到PropertyInfo调用的SetValue有什么限制
PropertyInfo.GetSetMethod 方法 (Boolean)

边栏推荐
- 深度学习——CV、CNN、RNN
- Should we test the Dao layer?
- [day_020419] inverted string
- [1]数学建模基础入门知识
- Find the original root
- [day_010418] delete public string
- 【Day05_0422】C语言选择题
- Niuke network: TOPK problem of additive sum between two ordinal groups
- Oc/swift Technology Download File (breakpoint continuation AFN download file alamofire Download File native download) (source code)
- [day03_0420] C language multiple choice questions
猜你喜欢

TPS Motion(CVPR2022)视频生成论文解读
![[fault diagnosis] bearing fault diagnosis based on Bayesian optimization support vector machine with matlab code](/img/9e/138e4b160fa9bd6486fac44a788d09.png)
[fault diagnosis] bearing fault diagnosis based on Bayesian optimization support vector machine with matlab code

RNN recurrent neural network

Markdown add Emoji expression

Force buckle - 3. Longest substring without repeated characters

Conda 虚拟环境envs目录为空

Slice and array of go

A tool for quickly switching local host files -- switchhosts

Code runner for vs code, with more than 40million downloads! Support more than 50 languages

Leetcode:934. The shortest Bridge
随机推荐
What is the concept and purpose of white box testing? And what are the main methods?
Deep learning - CV, CNN, RNN
C language introduction practice (7): switch case calculation of days in the year (normal year / leap year calculation)
If I want to listen to Jay Chou with you, I want you to listen to my whole youth
使用Scanner从键盘获取多种数据类型
[day_030420] find the longest consecutive number string in the string
Code Runner for VS Code,下载量突破 4000 万!支持超过50种语言
Force buckle - 4. Find the median of two positive arrays
【Day05_0422】C语言选择题
Conda 虚拟环境envs目录为空
BPG notes (IV)
Basis of multimodal semantic segmentation
Taobao pinduoduo Tiktok 1688 Suning taote jd.com and other keyword search commodity API interfaces (keyword search commodity API interface, keyword search commodity list interface, classification ID s
多目标检测
Vision Transformer 必读系列之图像分类综述
Huawei cloud koomessage is a new marketing weapon in the hot public beta
YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors
Yolov6: the fast and accurate target detection framework is open source
Swift basic FileManager (file management)
[pytorch] CNN practice - flower species identification