`
xiaoming2xiaohong
  • 浏览: 40789 次
社区版块
存档分类
最新评论

详解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中访问私有成员不是很难,这篇文章提供几个简单的方法让你如愿以偿。

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

1、得到私有字段的值:

<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);
}

2、得到私有属性的值:

<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>);
}

3、设置私有成员的值:

<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>4、设置私有属性的值: <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;">5、调用私有方法:</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>}

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

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

<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();

结果如下:

<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">

[size=small;]总结:[/size]实现对类私有成员的访问。

 
0
0
分享到:
评论

相关推荐

    c#语法详解c#语法详解c#语法详解

    - **域**:类的成员变量,可以是私有的(`private`)、公有的(`public`)或其他访问修饰符。 - **方法**:类的功能,包含行为和逻辑,如`void Display() { ... }` - **属性**:提供了访问类的私有域的公共接口,...

    C#单例模式详解 C#单例模式详解C#单例模式详解

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在C#中,单例模式常用于管理共享资源或控制类的实例化过程,以提高性能、节约系统资源,特别是在整个应用程序生命周期内只需要一...

    Visual C# 2008开发技术详解.rar

    在学习《Visual C# 2008开发技术详解》的过程中,读者将深入理解如何使用C# 2008进行程序设计,包括但不限于对象导向编程、异常处理、多线程、文件I/O、网络通信、数据库访问等。此外,还会接触到UI设计、单元测试、...

    c#_索引器详解C#经典教程

    在C#编程语言中,索引器是一种特殊的方法,它使得类或结构的实例能够像数组那样通过索引来访问其内部数据。索引器的概念在处理集合类或自定义数据结构时尤其有用,因为它提供了直观且灵活的访问方式。下面我们将深入...

    详解C#委托,事件,Observer设计模式

    ### 详解C#委托,事件,Observer设计模式 在C#编程中,了解并掌握委托、事件以及Observer设计模式对于构建高效、灵活的应用程序至关重要。本文将深入探讨这些概念,并通过具体的示例来帮助理解。 #### 1. 将方法...

    c#类成员(字段、属性、方法、事件)

    ### C#类成员详解:字段、属性、方法、事件 #### 字段:数据的封装与存储 在C#中,**字段**是类内部用于存储数据的成员,它允许类封装状态信息,使得对象能够拥有自己的数据。字段可以是任何数据类型,包括基本...

    C#入门教程手册详解

    C#的基本概念涵盖了声明、成员、成员访问、签名和重载、范围等,这些都是理解C#编程逻辑的基础。 #### 3.1 声明 声明定义了变量、方法、类等的类型和名称,是C#程序的基本组成单元。 #### 3.2 成员 成员是类、...

    C#编程语言详解 Part1

    ### C#编程语言详解 Part1 知识点总结 #### 一、简介 - **Hello World**: C#中创建一个简单的“Hello World”程序是非常直接的。这通常用于展示语言的基础语法,例如如何定义主方法(`Main`),以及如何使用控制台...

    c# 类成员的可访问性代码详解

    这是默认的类成员访问级别,用于封装实现细节。 ```csharp internal class MyClass { internal int InternalField; internal void InternalMethod() { } } ``` `InternalField` 和 `InternalMethod` 只能在包含 `...

    浅谈C#中Process类的使用详解

    在C#编程中,`Process`类是用于管理和控制操作系统进程的核心工具,它位于`System.Diagnostics`命名空间中。本文将深入探讨`Process`类的使用,包括获取、显示和操作进程的方法。 首先,`Process`类允许开发者获取...

    C#中的InputBox

    ### C#中的自定义InputBox实现 在C#编程中,开发者经常需要向用户收集输入数据,例如在登录界面获取用户名或密码,或者在表单中收集其他类型的用户信息。然而,与VB.NET中直接提供的`InputBox`功能不同,.NET ...

    详解C#中的属性和属性的使用

    在C#编程语言中,属性(Property)是一个重要的特性,它提供了一种安全且灵活的方式来存取类的私有字段值。属性本质上是封装了getter和setter方法的特殊成员,通常用于模拟公有数据成员,但又具备更好的控制和安全性...

    C#接口定义和继承的区别详解

    6. **成员访问权限**:接口中的成员只能是公共的,而类中的成员可以具有不同的访问级别(如私有、受保护等)。 7. **实例化**:接口不能被实例化,而类可以被实例化。 #### 四、示例 为了更直观地展示接口与继承的...

    C#委托事件详解

    事件是类的一个私有成员,只能由该类自身引发。其他类可以订阅这些事件,当事件发生时,订阅者注册的处理方法将被调用。这通常涉及到`EventHandler`类型的委托,它有两个参数:一个是发送事件的对象,另一个是包含...

    C# set get用法

    属性在C#中提供了一种灵活的方式来访问类的私有成员。它们看起来像公共字段,但实际上是一对特殊的方法,即`get`和`set`方法的组合。通过这些方法,我们可以在不暴露类的内部细节的情况下,让外部代码读取和修改类的...

    C#事件访问器详解

    在C#编程语言中,事件是实现发布-订阅模式的关键元素,它允许对象之间进行通信而不必知道彼此的具体实现。事件访问器则是控制事件订阅和取消订阅行为的特殊方法,通常与事件一起使用,提供了对事件处理程序添加和...

    C#2008 Keywords

    - **private**:私有成员,只能在定义它的类内部访问。 - **protected**:受保护成员,可以在当前类及其派生类中访问。 - **internal**:内部成员,只能在同一个程序集内访问。 ### 异常处理关键字详解 - **try**...

    C#中文转简拼

    ### C# 中文转简拼知识点详解 #### 一、简拼的概念 简拼是汉语拼音的简化形式,主要用于快速输入中文。它通常只保留每个汉字的声母和韵母的第一个字母,对于某些常用字,可能仅保留声母。例如,“中华人民共和国”...

    C# 修饰符:private protected internal public

    它可以帮助我们定义哪些成员(例如变量、方法等)可以被外部代码访问,哪些成员应该保持私有,只允许内部访问。C# 提供了四种访问修饰符来实现这一目的:`private`、`protected`、`internal` 和 `public`。本文将...

Global site tag (gtag.js) - Google Analytics