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

背景:项目中引用了一个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
    }
}

以上封装内容参照了http://www.cnblogs.com/8023-1314/archive/2012/12/14/2818743.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值