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

private string name;public string Name{ get { return name; } set { name = value; }}

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

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

 1、得到私有字段的值:

public static T GetPrivateField<T>(this object instance, string fieldname){ BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; Type type = instance.GetType(); FieldInfo field = type.GetField(fieldname, flag); return (T)field.GetValue(instance);}

2、得到私有属性的值:

public static T GetPrivateProperty<T>(this object instance, string propertyname){ BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; Type type = instance.GetType(); PropertyInfo field = type.GetProperty(propertyname, flag); return (T)field.GetValue(instance, null);}

3、设置私有成员的值:

public static void SetPrivateField(this object instance, string fieldname, object value) 

    BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; 
    Type type = instance.GetType(); 
    FieldInfo field = type.GetField(fieldname, flag); 
    field.SetValue(instance, value); 

4、设置私有属性的值: 
public static void SetPrivateProperty(this object instance, string propertyname, object value) 

    BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; 
    Type type = instance.GetType(); 
    PropertyInfo field = type.GetProperty(propertyname, flag); 
    field.SetValue(instance, value, null); 

5、调用私有方法:

public static T CallPrivateMethod<T>(this object instance, string name, params object[] param)
{
    BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
    Type type = instance.GetType();
    MethodInfo method = type.GetMethod(name, flag);
    return (T)method.Invoke(instance, param);
}

测试:

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

public class TestClass{ public TestClass() { privatefield1 = 1;
privatefield2 = 99; PrivateFieldA = "Lo"; PrivateFieldB = "ve"; }
private int privatefield1; private int privatefield2; private string
PrivateFieldA { get; set; } private string PrivateFieldB { get; set; }
private int Add() { return privatefield1 + privatefield2; } private
string Join() { return PrivateFieldA + PrivateFieldB; }}

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

TestClass obj = new
TestClass();System.Console.WriteLine("私有字段");System.Console.WriteLine(obj.GetPrivateField<int>("privatefield1"));System.Console.WriteLine(obj.GetPrivateField<int>("privatefield2"));System.Console.WriteLine("私有属性");System.Console.WriteLine(obj.GetPrivateProperty<string>("PrivateFieldA"));System.Console.WriteLine(obj.GetPrivateProperty<string>("PrivateFieldB"));System.Console.WriteLine("私有方法");System.Console.WriteLine(obj.CallPrivateMethod<int>("Add",null));System.Console.WriteLine(obj.CallPrivateMethod<string>("Join",

null));System.Console.WriteLine("修改私有属性");obj.SetPrivateProperty("PrivateFieldA",
"hello");obj.SetPrivateProperty("PrivateFieldB",
"world");System.Console.WriteLine(obj.CallPrivateMethod<string>("Join",
null));System.Console.Read();

结果如下:

使用C#反射机制访问类的私有成员【转】的更多相关文章

  1. Delphi 跨单元进入(访问)类的私有成员,protected ,private部分

    http://blog.sina.com.cn/s/blog_5f8861b60102v1nl.html Delphi 跨单元进入(访问)类的私有成员,protected ,private部分 (20 ...

  2. VC6.0中重载操作符函数无法访问类的私有成员

    整理日: 2015年03月18日 在 C++ 中,操作符(运算符)可以被重载以改写其实际操作.同时我们可以定义一个函数为类的朋友函数(friend function)以便使得这个函数能够访问类的私有成 ...

  3. C#箴言之用属性来访问类的私有成员

    在程序中,难免要访问某个对象的私有成员.那么以前实现这类功能的方法有两种,第一种方法最简单,就是把成员访问符从“private”改为“public”即可:而另一个就是提供公有的成员访问函数来进行访问. ...

  4. C#使用反射机制获取类信息[转]

    http://www.cnblogs.com/zhoufoxcn/archive/2006/10/31/2515873.html 1.用反射动态创建类实例,并调用其公有成员函数. //新建一个类库项目 ...

  5. C#使用反射机制获取类信息

    1.用反射动态创建类实例,并调用其公有成员函数. //新建一个类库项目,增加一个GetSum方法. using System;   namespace ClassLibrary1 {    publi ...

  6. java利用反射访问类的私有(private)属性及方法

    Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...

  7. 【转】Java利用反射机制访问私有化构造器

    Java利用反射机制访问私有化构造器 博客分类: java   我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...

  8. c++中嵌套类,外部类访问内部类的私有成员变量

    在嵌套类中,内部类可以直接访问外部类的私有成员变量,但是外部类不能直接访问内部类的私有成员变量,必须把外部类声明为内部类的友元类 /********************************** ...

  9. C++之在类内部访问对象的私有成员

    一.引言 今天看项目里的一段代码发现,竟然可以再类的成员函数中访问该类的对象的私有成员.感觉不可思议. 自己写的实例代码: #include <iostream> using namesp ...

随机推荐

  1. C++最快的读取文件的方案(scanf,cin(及取消sync),fread)的详细对比

    竞赛中,遇到大数据时,往往读文件成了程序运行速度的瓶颈,需要更快的读取方式.相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,于是从此以后发誓不用cin读数据.还有人说Pascal的rea ...

  2. 使用 IntraWeb (12) - 基本控件之 TIWGradButton、TIWImageButton

    TIWGradButton.TIWImageButton 分别是有颜色梯度变化按钮和图像按钮. TIWGradButton 所在单元及继承链: IWCompGradButton.TIWGradButt ...

  3. spring cloud 学习(7) - 生产环境如何不停机热发布?

    业务繁忙的系统,原则上是不允许停机的,那么问题来了,如果真有严重的bug要修复,不得不发布,怎么做到不停机发布,对业务无感知呢? eureka 提供了一系列rest url,可以对注册实例进行操作,比 ...

  4. JTAG TAP Controller

    The TAP controller is a synchronous finite state machine that responds to changes at the TMS and TCK ...

  5. java数据结构 栈stack

    栈(Stack) 栈(Stack)实现了一个后进先出(LIFO)的数据结构. 你可以把栈理解为对象的垂直分布的栈,当你添加一个新元素时,就将新元素放在其他元素的顶部. 当你从栈中取元素的时候,就从栈顶 ...

  6. /bin/sh^M: bad interpreter:没有那个文件或目录解决

    /bin/sh^M: bad interpreter:没有那个文件或目录解决   执行脚本时发现如下错误: /bin/sh^M: bad interpreter: 没有那个文件或目录   错误分析: ...

  7. Java File.separator

    在Windows下的路径分隔符和Linux下的路径分隔符是不一样的,当直接使用绝对路径时,跨平台会暴出“No such file or diretory”的异常. 比如说要在temp目录下建立一个te ...

  8. Vmware ESXi添加共享磁盘

        1,ssh登录(两个虚拟机所在的宿主机)物理主机,创建共享磁盘(该步骤也可图形化操作) #cd /vmfs/volumes/4ffd9951-2c12a99a-ff2a-3440b59cd4f ...

  9. Safari支不支持HTML5录音? 现在浏览器中最好的解决方案是WebRTC下的 navigator.getUserMedia API。

    先放结论:Safari支不支持HTML5录音? ——据我调查,不支持. 现在浏览器中最好的解决方案是WebRTC下的 navigator.getUserMedia API. 可是当使用Can I us ...

  10. Spring Websocket实现文本、图片、声音、文件下载及推送、接收及显示(集群模式)

    相关环境 Nginx,Spring5.x当前(要选择4.0+),tomcat8.x,Quartz 2.x集群(实际运用是Quartz的集群模式和单机模式共存的) 测试面页:http://sms.rey ...