您的位置:首页 > 编程语言 > C#

C# 利用反射访问修改私有成员

2014-12-29 19:38 393 查看
背景:项目中引用了一个dll,dll中有个自定义控件,自定义控件中有一个打印控件(Private),我的项目要根据权限设置打印控件的一些按钮是否显示

即:修改外部dll的私有控件控件属性。

刚开始想到的就是反射,但是怎么也获取不到这个属性,只能获取公共成员(public),

原来私有成员要不同的搜索类型(System.Reflection.BindingFlags)枚举。

private void FrmControlShow_Shown(object sender, EventArgs e)
{
Microsoft.Reporting.WinForms.ReportViewer newControl = bizReportCongtrol.GetPrivateField<Microsoft.Reporting.WinForms.ReportViewer>("MainReportViewer");
newControl.ShowExportButton = false;
newControl.ShowPrintButton = false;
bizReportCongtrol.SetPrivateField("MainReportViewer", newControl);
}


将方式获取变量值和设置变量值封装在一个静态类中

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

public static void SetPrivateField(this ReportControl.BizRdlCongtrol 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);
}
}


这边对私有成员的操作做了一个封装(可直接拷贝使用),这边的扩展类型可以自己修改成想要的类型,不一定要用object

using System;
using System.Reflection;

namespace OperateCommon
{
public static class OperatePrivate
{
#region 字段

/// <summary>
/// 获得私有字段的值
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="fieldname">私有字段名称 string</param>
/// <returns>私有字段值 T</returns>
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);
}

/// <summary>
/// 设置私有字段的值
/// </summary>
/// <param name="instance">扩展对象类型</param>
/// <param name="fieldname">私有字段名称 string</param>
/// <param name="value">私有字段新值 object</param>
public static void SetPrivateField(this ReportControl.BizRdlCongtrol 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);
}

#endregion

#region 属性

/// <summary>
/// 获取私有属性的值
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="propertyname">私有属性名称 string</param>
/// <returns>私有字段值 T</returns>
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);
}

/// <summary>
/// 设置私有属性的值
/// </summary>
/// <param name="instance">扩展对象类型</param>
/// <param name="propertyname">私有属性名称</param>
/// <param name="value">私有属性新值</param>
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);
}

#endregion

#region 方法

/// <summary>
/// 调用私有方法
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="name">私有属性名称 string</param>
/// <param name="param">参数列表 object</param>
/// <returns>调用方法返回值</returns>
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);
}

#endregion
}
}


以上封装内容参照了/article/5545316.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: