当前位置:网站首页>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)

边栏推荐
- Leetcode 347. top k high frequency elements
- Registration conditions for system integration project management engineer (intermediate level of soft exam) in the second half of 2022
- [nanny level] package volume optimization tutorial
- Design principle of infrared circuit of single chip microcomputer
- 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
- 【Day04_0421】C语言选择题
- Map dictionary and constraints of go
- English sentence pattern reference exclusive Edition - attributive clause
- If I want to listen to Jay Chou with you, I want you to listen to my whole youth
- @ConstructorProperties注解理解以及其对应使用方式
猜你喜欢
随机推荐
YOLOv6:又快又准的目标检测框架开源啦
Leetcode:741. picking cherries
BigDecimal becomes negative
Registration conditions for system integration project management engineer (intermediate level of soft exam) in the second half of 2022
[untitled]
If I want to listen to Jay Chou with you, I want you to listen to my whole youth
Advanced C language - archived address book (file)
Regular expressions and calling related functions in C language
带你搞透IO多路复用原理(select、poll和epoll)
[day_070425] legal bracket sequence judgment
What are the aspects of performance testing? What are the classification and testing methods?
【故障诊断】基于贝叶斯优化支持向量机的轴承故障诊断附matlab代码
英语句式参考纯享版 - 定语从句
【Day_01 0418】删除公共字符串
[Web3 series development tutorial - create your first NFT (4)] what can NFTs bring to you
[day05_0422] C language multiple choice questions
Taobao JD pinduoduo Tiktok taote 1688 and other multi platform commodity app details API interfaces (commodity details page data interface, commodity sales interface, keyword search commodity sales in
Servlet无法直接获取request请求中的JSON格式数据
Swift basic FileManager (file management)
Multi target detection


![[untitled]](/img/42/5e8b62edc0aa289098425b26df2453.jpg)





