详解C#中访问私有成员

首先我必须承认访问一个类的私有成员不是什么好做法。大家也都知道私有成员在外部是不能被访问的。而一个类中会存在很多私有成员:如私有字段、私有属性、私有方法。对于私有成员访问,可以套用下面这种非常好的方式去解决。

<span style="color: blue;">private string </span>name;
<span style="color: blue;">public string </span>Name
{
<span style="color: blue;">get
</span>{
<span style="color: blue;">return </span>name;
}
<span style="color: blue;">set
</span>{
name = <span style="color: blue;">value</span>;
}
}

<a href="http://11011.net/software/vspaste"></a>

但是有时候,源代码是别人的,你就不能修改源代码,只提供给你dll。或者你去维护别人的代码,源代码却有丢失。这样的情况如果你想知道私有成员的值,甚至去想直接调用类里面的私有方法。那怎么办呢?其实在.net中访问私有成员不是很难,这篇文章提供几个简单的方法让你如愿以偿。

为了让代码用起来优雅,使用扩展方法去实现。

[b] 1、得到私有字段的值:[/b]

<span style="color: blue;">public static </span>T GetPrivateField<T>(<span style="color: blue;">this object </span>instance, <span style="color: blue;">string </span>fieldname)
{
<span style="color: #2b91af;">BindingFlags </span>flag = <span style="color: #2b91af;">BindingFlags</span>.Instance | <span style="color: #2b91af;">BindingFlags</span>.NonPublic;
<span style="color: #2b91af;">Type </span>type = instance.GetType();
<span style="color: #2b91af;">FieldInfo </span>field = type.GetField(fieldname, flag);
<span style="color: blue;">return </span>(T)field.GetValue(instance);
}

[b]2、得到私有属性的值:[/b]

<span style="color: blue;">public static </span>T GetPrivateProperty<T>(<span style="color: blue;">this object </span>instance, <span style="color: blue;">string </span>propertyname)
{
<span style="color: #2b91af;">BindingFlags </span>flag = <span style="color: #2b91af;">BindingFlags</span>.Instance | <span style="color: #2b91af;">BindingFlags</span>.NonPublic;
<span style="color: #2b91af;">Type </span>type = instance.GetType();
<span style="color: #2b91af;">PropertyInfo </span>field = type.GetProperty(propertyname, flag);
<span style="color: blue;">return </span>(T)field.GetValue(instance, <span style="color: blue;">null</span>);
}

[b]3、设置私有成员的值:[/b]

<span style="color: blue;">public static void </span>SetPrivateField(<span style="color: blue;">this object </span>instance, <span style="color: blue;">string </span>fieldname, <span style="color: blue;">object </span>value) <br>{ <br><span style="color: #2b91af;">BindingFlags </span>flag = <span style="color: #2b91af;">BindingFlags</span>.Instance | <span style="color: #2b91af;">BindingFlags</span>.NonPublic; <br><span style="color: #2b91af;">Type </span>type = instance.GetType(); <br><span style="color: #2b91af;">FieldInfo </span>field = type.GetField(fieldname, flag); <br> field.SetValue(instance, value); <br>} <br>[b]4、设置私有属性的值:[/b] <br><span style="color: blue;">public static void </span>SetPrivateProperty(<span style="color: blue;">this object </span>instance, <span style="color: blue;">string </span>propertyname, <span style="color: blue;">object </span>value) <br>{ <br><span style="color: #2b91af;">BindingFlags </span>flag = <span style="color: #2b91af;">BindingFlags</span>.Instance | <span style="color: #2b91af;">BindingFlags</span>.NonPublic; <br><span style="color: #2b91af;">Type </span>type = instance.GetType(); <br><span style="color: #2b91af;">PropertyInfo </span>field = type.GetProperty(propertyname, flag); <br> field.SetValue(instance, value, <span style="color: blue;">null</span>); <br>} <br><span style="font-family: Verdana;">[b]5、调用私有方法:[/b]</span>

<span style="color: blue;">public static </span>T CallPrivateMethod<T>(<span style="color: blue;">this object </span>instance, <span style="color: blue;">string </span>name, <span style="color: blue;">params object</span>[] param)<br>{<br><span style="color: #2b91af;">BindingFlags </span>flag = <span style="color: #2b91af;">BindingFlags</span>.Instance | <span style="color: #2b91af;">BindingFlags</span>.NonPublic;<br><span style="color: #2b91af;">Type </span>type = instance.GetType();<br><span style="color: #2b91af;">MethodInfo </span>method = type.GetMethod(name, flag);<br><span style="color: blue;">return </span>(T)method.Invoke(instance, param);<br>}

[b][size=medium;]测试:[/size][/b]

下面我们使用一个测试类,进行测试。新建一个类库项目,测试的类代码如下:

<span style="color: blue;">public class </span><span style="color: #2b91af;">TestClass
</span>{
<span style="color: blue;">public </span>TestClass()
{
privatefield1 = 1;
privatefield2 = 99;
PrivateFieldA = <span style="color: #a31515;">"Lo"</span>;
PrivateFieldB = <span style="color: #a31515;">"ve"</span>;
}
<span style="color: blue;">private int </span>privatefield1;
<span style="color: blue;">private int </span>privatefield2;
<span style="color: blue;">private string </span>PrivateFieldA
{
<span style="color: blue;">get</span>;
<span style="color: blue;">set</span>;
}
<span style="color: blue;">private string </span>PrivateFieldB
{
<span style="color: blue;">get</span>;
<span style="color: blue;">set</span>;
}
<span style="color: blue;">private int </span>Add()
{
<span style="color: blue;">return </span>privatefield1 + privatefield2;
}
<span style="color: blue;">private string </span>Join()
{
<span style="color: blue;">return </span>PrivateFieldA + PrivateFieldB;
}
}

将上面类库的dll引入控制台项目中。使用下面代码去使用这个类的私有成员:

<span style="color: #2b91af;">TestClass </span>obj = <span style="color: blue;">new </span><span style="color: #2b91af;">TestClass</span>();
System.<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"私有字段"</span>);
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.GetPrivateField<<span style="color: blue;">int</span>>(<span style="color: #a31515;">"privatefield1"</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.GetPrivateField<<span style="color: blue;">int</span>>(<span style="color: #a31515;">"privatefield2"</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"私有属性"</span>);
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.GetPrivateProperty<<span style="color: blue;">string</span>>(<span style="color: #a31515;">"PrivateFieldA"</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.GetPrivateProperty<<span style="color: blue;">string</span>>(<span style="color: #a31515;">"PrivateFieldB"</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"私有方法"</span>);
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.CallPrivateMethod<<span style="color: blue;">int</span>>(<span style="color: #a31515;">"Add"</span>,<span style="color: blue;">null</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.CallPrivateMethod<<span style="color: blue;">string</span>>(<span style="color: #a31515;">"Join"</span>, <span style="color: blue;">null</span>));
System.<span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"修改私有属性"</span>);
obj.SetPrivateProperty(<span style="color: #a31515;">"PrivateFieldA"</span>, <span style="color: #a31515;">"hello"</span>);
obj.SetPrivateProperty(<span style="color: #a31515;">"PrivateFieldB"</span>, <span style="color: #a31515;">"world"</span>);
System.<span style="color: #2b91af;">Console</span>.WriteLine(obj.CallPrivateMethod<<span style="color: blue;">string</span>>(<span style="color: #a31515;">"Join"</span>, <span style="color: blue;">null</span>));
System.<span style="color: #2b91af;">Console</span>.Read();

结果如下:

[url=http://images.cnblogs.com/cnblogs_com/zhuqil/WindowsLiveWriter/C_13ACF/hhh_2.jpg]<img style="display: inline; border-width: 0px;" title="hhh" src="http://images.cnblogs.com/cnblogs_com/zhuqil/WindowsLiveWriter/C_13ACF/hhh_thumb.jpg" border="0" alt="hhh" width="611" height="398">[/url]

[size=small;][b]总结:[/b][/size]实现对类私有成员的访问。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值