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

边栏推荐
- 【Web3 系列开发教程——创建你的第一个 NFT(4)】NFTs 可以给你带来什么
- 力扣5: 最长回文子串
- Sequential action localization | fine grained temporal contrast learning for weak supervised temporal action localization (CVPR 2022)
- Why use the static keyword when defining methods
- [untitled]
- Three skills are needed to engage in SAP related work
- 【C语言】文件操作
- Intelligent fire protection application based on fire GIS system
- 【Day_04 0421】进制转换
- 【Day_06 0423】不要二
猜你喜欢

Map collection inheritance structure

JVM class loading and GC garbage collection mechanism

RNN循环神经网络
![[C language] file operation](/img/19/5bfcbc0dc63d68f10155e16d99581c.png)
[C language] file operation

Mobile web

【pytorch】CNN实战-花朵种类识别

Multi target detection

What is the concept and purpose of white box testing? And what are the main methods?

Deep learning - CV, CNN, RNN

Concurrency opening -- take you from 0 to 1 to build the cornerstone of concurrency knowledge system
随机推荐
性能测试包括哪些方面?分类及测试方法有哪些?
【Day_03 0420】数组中出现次数超过一半的数字
[day_060423] no two
使用Scanner从键盘获取多种数据类型
[1]数学建模基础入门知识
IP day 10 notes - BGP
nuxt 配置主题切换
将一个正整数分解质因数,要求分解成尽可能小的多个的因数。
Database and the future of open source
[untitled]
YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors
Do it yourself smart home: intelligent air conditioning control
CCTV dialogue ZTE: why must the database be in your own hands?
What are the main reasons for server crash
力扣——3. 无重复字符的最长子串
[day_020419] inverted string
【无标题】
【Day04_0421】C语言选择题
[day04_0421] 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