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

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. java中Optional和Stream流的部分操作

    package test9; import java.util.DoubleSummaryStatistics; import java.util.Optional; import java.util ...

  2. Django模版语言inclusion_tag的用法。

        inclusion_tag.它多用于一个HTML片段的.例如我写的一个BBS项目中. 一个博主的主页面的左侧栏和查看博主某篇文章的页面的左栅栏的一样的.为了不用重复写同样的代码.且提高页面的扩 ...

  3. BZOJ4239 : 巴士走读

    考虑按时刻从早到晚模拟,计算出 f[i]:到达i点的最晚出发时间 g[i]:为了赶上第i辆车的最晚出发时间 然后将所有到达n号点的巴士按到达时间排序,查询的时候二分查找即可. 时间复杂度$O(n\lo ...

  4. springmvc学习总结(二) -- maven+springmvc+spring+mybatis+mysql详细搭建整合过程讲解

    @_@ 写在最前 之前分享过下面这几篇: mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上)(附demo和搭建过程遇到的问题解决方法) myba ...

  5. Codeforces Round #371 (Div. 2) A. Meeting of Old Friends 水题

    A. Meeting of Old Friends 题目连接: http://codeforces.com/contest/714/problem/A Description Today an out ...

  6. mySql---剖析InnoDB索引原理

    摘要: 本篇为参考别人的文章(http://blog.csdn.net/voidccc/article/details/40077329) 1 各种树形结构 本来不打算从二叉搜索树开始,因为网上已经有 ...

  7. SSH公钥登录原理

    在平时工作中我们经常要远程登录服务器,这就要用到SSH协议: $ ssh user@host 主要有两种登录方式:第一种为密码口令登录,第二种为公钥登录 密码口令登录 通过密码进行登录,主要流程为: ...

  8. [原创]App性能测试指标篇

    [原创]App性能测试指标篇 目前由于苹果,三星等大厂对智能手机的研发及投入,使的智能手机发展非常迅速,每个人手中都有一些离不开生活的App,如:微信,微博,百度或是各游戏App等,但是到底App性能 ...

  9. 【Go命令教程】2. go build

    go build 命令用于编译我们 指定的  源码文件 或 代码包 以及它们的依赖包. 例如,如果我们在执行 go build 命令时不后跟任何代码包,那么命令将试图编译当前目录所对应的代码包.例如, ...

  10. Godaddy新手教程

    Godaddy新版域名空间管理控制面板使用方法和更换IP与机房问题 http://www.freehao123.com/godaddy-new/ //设置DNS 最新Godaddy绑定域名教程设置DN ...