如何在程序运行时动态修改一个类的属性的get;set;?

问题描述

publicclassMyTestClass{privatestring_name;publicstringName{get{returnstring.Format("名字:{0}",_name);}set{value=value??string.Empty;_name=value.Substring(0,4);}}}publicstaticvoidMain(){DynamicMethodmethod=newDynamicMethod("Set_Name",typeof(string),newType[]{typeof(object),typeof(object)});varil=method.GetILGenerator();il.Emit(OpCodes.Ldarg,0);il.Emit(OpCodes.Ldarg,1);//dosomethingvarname=typeof(MyTestClass).GetProperty("Name");name.SetMethod=method;//setmethod只读}

我想在运行时修改MyTestClass类中Name属性的set方法。请问如何去实现?

解决方案

解决方案二:
将get/set方法定义成虚方法,运行时用emit创建它的派生类,重写这些方法,这是最简单的。
解决方案三:
这不是一个取值一个赋值,我没看懂你的问题
解决方案四:
怎么个改法?说具体点
解决方案五:
就像版主说的,将set和get做成虚方法,派生类重写虚方法,然后用反射发出来动态创建派生对象。
解决方案六:
一个常见的、浪漫的、但又无奈的误会:Emit可以修改编译时已存在的类
解决方案七:
引用1楼caozhy的回复:

将get/set方法定义成虚方法,运行时用emit创建它的派生类,重写这些方法,这是最简单的。

具体应该怎么弄?给点伪代码。。你这么一说我想起EF的属性的lazyload。。。
解决方案八:
引用1楼caozhy的回复:

将get/set方法定义成虚方法,运行时用emit创建它的派生类,重写这些方法,这是最简单的。

我看明白了。。你意思是想将MyTestClass的name设为virtual。我使用的时候还要,动态创建一个类(DefineType)继承MyTestClass。然后重写name属性。。然后再将属性的setvalue方法绑定为我想要的结果。。。这样成本太高了。。有没有其它办法
解决方案九:
引用5楼phommy的回复:

一个常见的、浪漫的、但又无奈的误会:Emit可以修改编译时已存在的类

我觉得应该,也许,可能行。。。
解决方案十:
我就想知道为什么要这么做……
解决方案十一:
引用9楼starfd的回复:

我就想知道为什么要这么做……

拿EF举例我实体(A)中有个属性(B)关联了其它表。我不想在查A的时候把B带出来。但我又想在A访问B属性的时候去执行查询。。现在出现了2种情况。。一种是默认全部带出来。。这时属性B直接getreturnvalue;set_field=value就可以了。。另一种情况就是我上面说的了,我就需要修改属性B的get方法。。让它执行我定义的方法,这个方法是执行查询,returnB类型大概情况就像这样,我的需求也是有2种情况产生。。因为EF可以,我就觉得肯定可以这样做。。
解决方案十二:
引用9楼starfd的回复:

我就想知道为什么要这么做……

因为EF在lazyload的时候将属性也设为了virtual。。根据版主给出的回复,我怀疑EF也是这样做的。运行时用emit创建它的派生类,重写这些属性。。
解决方案十三:
这个估计就是用了Lazy<T>而已吧……
解决方案十四:
引用10楼lyj224170707的回复:

Quote: 引用9楼starfd的回复:
我就想知道为什么要这么做……

拿EF举例我实体(A)中有个属性(B)关联了其它表。我不想在查A的时候把B带出来。但我又想在A访问B属性的时候去执行查询。。现在出现了2种情况。。一种是默认全部带出来。。这时属性B直接getreturnvalue;set_field=value就可以了。。另一种情况就是我上面说的了,我就需要修改属性B的get方法。。让它执行我定义的方法,这个方法是执行查询,returnB类型大概情况就像这样,我的需求也是有2种情况产生。。因为EF可以,我就觉得肯定可以这样做。。

.我看的有点晕,我不晓得是不是理解错了,我的理解是你想让你的B属性只给A自己访问,不给外面访问。。。就这样:privatestring_name;publicstringName{privateget{returnstring.Format("名字:{0}",_name);}set{_name=value;}}

解决方案十五:
引用1楼caozhy的回复:

将get/set方法定义成虚方法,运行时用emit创建它的派生类,重写这些方法,这是最简单的。

publicclassMyTestClass{privatestring_name;publicvirtualstringName{get{returnstring.Format("名字:{0}",_name);}set{value=value??string.Empty;_name=value.Substring(0,4);}}}publicstaticvoidMain(){varassembly=AppDomain.CurrentDomain.DefineDynamicAssembly(newAssemblyName("myAss"),AssemblyBuilderAccess.RunAndSave);varmodule=assembly.DefineDynamicModule("myModule","myModule.dll");varmyClass=module.DefineType("MyTestClass2",TypeAttributes.Public,typeof(MyTestClass));varproperty_Name=myClass.DefineProperty("Name",PropertyAttributes.None,typeof(string),null);vartype=myClass.CreateType();//报错。。MyTestClass访问被拒绝objectobj=type.GetConstructor(newType[0]).Invoke(null);}

报错了--。。是不是没在同一程序集。。如何改。。
解决方案:
引用13楼lc316546079的回复:

Quote: 引用10楼lyj224170707的回复:
Quote: 引用9楼starfd的回复:
我就想知道为什么要这么做……

拿EF举例我实体(A)中有个属性(B)关联了其它表。我不想在查A的时候把B带出来。但我又想在A访问B属性的时候去执行查询。。现在出现了2种情况。。一种是默认全部带出来。。这时属性B直接getreturnvalue;set_field=value就可以了。。另一种情况就是我上面说的了,我就需要修改属性B的get方法。。让它执行我定义的方法,这个方法是执行查询,returnB类型大概情况就像这样,我的需求也是有2种情况产生。。因为EF可以,我就觉得肯定可以这样做。。

.我看的有点晕,我不晓得是不是理解错了,我的理解是你想让你的B属性只给A自己访问,不给外面访问。。。就这样:privatestring_name;publicstringName{privateget{returnstring.Format("名字:{0}",_name);}set{_name=value;}}

不是。。我是想让我的Name的get执行我特定的代码。。而些特定的代码是在程序运行时动态添加的
解决方案:
你代码那个错是因为把MyTestClass类定义在了私有的Program里面,所以别的程序集的类是没法“看到”它的,当然没法继承。这种技术叫动态代理,EF的延迟加载就是用的这种技术。一般是两种方式,一种是拦截虚方法,还有就是通过接口拦截。这些功能不少动态AOP框架和IoC/DI框架都有,自己写还不如用第三方框架,比如,LightInject是个轻量级IoC容器,有扩展实现动态代理。最简单的例子:varc=newServiceContainer();c.Register<MyTestClass>();c.Intercept(mi=>mi.IsPropertyGetter(),ii=>"Hello");varm=c.GetInstance<MyTestClass>();Console.WriteLine(m.Name);

解决方案:
引用16楼github_22161131的回复:

你代码那个错是因为把MyTestClass类定义在了私有的Program里面,所以别的程序集的类是没法“看到”它的,当然没法继承。这种技术叫动态代理,EF的延迟加载就是用的这种技术。一般是两种方式,一种是拦截虚方法,还有就是通过接口拦截。这些功能不少动态AOP框架和IoC/DI框架都有,自己写还不如用第三方框架,比如,LightInject是个轻量级IoC容器,有扩展实现动态代理。最简单的例子:varc=newServiceContainer();c.Register<MyTestClass>();c.Intercept(mi=>mi.IsPropertyGetter(),ii=>"Hello");varm=c.GetInstance<MyTestClass>();Console.WriteLine(m.Name);

非常感谢你的解答,你给的就是我想要的东西。。但有个问题还想请教下usingSystem;usingSystem.Threading;usingSystem.Reflection;usingSystem.Reflection.Emit;usingSystem.Linq;usingEmit;usingSystem.Diagnostics;usingSystem.Collections.Generic;usingSystem.Collections;publicclassMyTestClass{privatestring_name;publicvirtualstringName{get{returnstring.Format("名字:{0}",_name);}set{value=value??string.Empty;_name=value.Substring(0,4);}}}classDynamicJumpTableDemo{publicstaticvoidMain(){varassembly=AppDomain.CurrentDomain.DefineDynamicAssembly(newAssemblyName("myAss"),AssemblyBuilderAccess.RunAndSave);varmodule=assembly.DefineDynamicModule("myModule","myModule.dll");varmyClass=module.DefineType("MyTestClass2",TypeAttributes.Public,typeof(MyTestClass));varmethod=myClass.DefineMethod("setvalue",MethodAttributes.Public|MethodAttributes.Virtual,null,newType[]{typeof(string)});varilm=method.GetILGenerator();varfield=myClass.DefineField("_name",typeof(string),FieldAttributes.Private);//这个不能用//varfield=myClass.BaseType.GetField("_name",BindingFlags.NonPublic|BindingFlags.Instance);ilm.Emit(OpCodes.Ldarg,0);ilm.Emit(OpCodes.Ldarg,1);ilm.Emit(OpCodes.Stfld,field);ilm.Emit(OpCodes.Ret);myClass.DefineMethodOverride(method,typeof(MyTestClass).GetProperty("Name").GetSetMethod());varobj=myClass.CreateType().GetConstructor(newType[0]).Invoke(null);varname=obj.GetType().GetProperty("Name");name.SetValue(obj,"888888888888888");}}

我在子类重写了父类中的name的setvalue方法。。问题出现在varfield=myClass.DefineField("_name",typeof(string),FieldAttributes.Private);//这个不能用//varfield=myClass.BaseType.GetField("_name",BindingFlags.NonPublic|BindingFlags.Instance);ilm.Emit(OpCodes.Ldarg,0);ilm.Emit(OpCodes.Ldarg,1);ilm.Emit(OpCodes.Stfld,field);ilm.Emit(OpCodes.Ret);我不能给MyTestClass的_name字段赋值。。这是为什么?不能对父类的属性进行操作吗?只能自己另外建1个吗?
解决方案:
原来是访问级别的问题。。蛋疼

时间: 2024-08-19 04:34:31

如何在程序运行时动态修改一个类的属性的get;set;?的相关文章

程序运行时出现的一个问题,求助

问题描述 //做一个简单的抽数字的例子.<?xmlversion="1.0"encoding="utf-8"?><mx:ApplicationapplicationComplete="aa"xmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute"><mx:Buttonx="124"y="2

mfc-vs2003编译的程序运行时总是多出一个无用的窗口,求解

问题描述 vs2003编译的程序运行时总是多出一个无用的窗口,求解 vs2003编译的程序运行时总是多出一个无用的窗口,就是在任务上多出一个没有标题,点击有不出现任何窗口的那么一个东西,不知道是什么,求解!

调试-MFC 程序运行时出现空指针

问题描述 MFC 程序运行时出现空指针 MFC程序在启动过程中对一个变量进行初始化,之后放在定时器里运行,第一次执行时正常的,从第二次开始就出现空指针.采用单步调试每次都进入反编译页面,按F5键再次进入定时器变量依然为空指针,请问大家有没有遇到过这样的问题,怎么解决的?? 解决方案 具体要看程序.像数组越界之类的隐蔽bug也可能造成对变量的无意修改. 解决方案二: python 程序运行时出现DLL load errorjava--程序运行时出现内存溢出VC++程序运行时出现Runtime er

LINQ to SQL运行时动态构建查询条件

在进行数据查询时,经常碰到需要动态构建查询条件.使用LINQ实现这个需求可能会比以前拼接SQL语 句更麻烦一些.本文介绍了3种运行时动态构建查询条件的方法.本文中的例子最终实现的都是同一个功 能,从Northwind数据库Customers表中搜索出CompanyName列带有keywords中任意元素的项.keywords是 个字符串数组,该数组长度在编译时是不确定的.思路及方法说明写在代码注释中. 1.表达式树 1 public static IEnumerable<Customers>

[开发故事]第四回:应用反射在运行时动态获取类型信息

引言 网友hbfly,对于我在[你必须知道的.NET]第三十回:.NET十年(下)一文中 关于"当应用attribute进行运行时反射"的论述,希望举例说明,他提出了自己 的想法:[你必须知道的.NET]第二十四回:认识元数据和IL(上)[你必须知道的.NET]第二十五回:认识元数据和IL(中)[你必须知道的.NET]第二十六回:认识元数据和IL(下) [MyAttribute("text.....")] public mymethod() { //我可以再方法内部

php运行时动态创建函数的方法

 这篇文章主要介绍了php运行时动态创建函数的方法,涉及php流程语句与create_function函数的使用技巧,需要的朋友可以参考下     本文实例讲述了php运行时动态创建函数的方法.分享给大家供大家参考.具体分析如下: 一般的语言函数必须定义了在运行,而php支持在运行时动态创建函数,下面是一个简单的范例,在运动时根据不同的条件创建函数$a ? 1 2 3 4 5 6 7 8 9 10 11 <?php if (count($_POST) > 0) { $prepped = cre

控制-自己编的程序运行时串口被程序自己占用,如何用代码强制关闭重新连接?

问题描述 自己编的程序运行时串口被程序自己占用,如何用代码强制关闭重新连接? 我用vs2010基于MFC编一个小程序,其中有一部分是用单片机转USB串口与电脑程序相连.现在问题是: 不小心动了Usb线的话,程序会卡住,在想打开串口会显示串口被占用(就是自己的程序占用).需要把USB线拔下来才能解决问题.求大侠指导,能不能用代码控制,按个软件上的button,就能自动连接上com1. 求大侠指导! 解决方案 结束进程再重启看看行不行.首先要确定卡死不是驱动的问题,如果是驱动的问题,程序就无能为力了

java-hibernate程序运行现多出一个记录

问题描述 hibernate程序运行现多出一个记录 person2 和 emails 一对多. List list = session.createQuery( select p from Person2 p left join fetch p.emails e "" + "" where e.email like '%@yahoo.com.cn' "").list(); **//对应的sql语句执 行正常 ,调试看到 list取出来多出一条记录

using-为什么ASP.NET程序运行时不执行,也不报错?急急,哪位大蚁帮我一把戏?

问题描述 为什么ASP.NET程序运行时不执行,也不报错?急急,哪位大蚁帮我一把戏? 点发布时,屏幕闪一下,没有任何提示,不进行验证,也没有加到SQL2005库中! 前台: <%@ Page Language="C#" validateRequest="false" CodeFile="kjxm_Edit.aspx.cs" Inherits="As_Tzxm_Edit" %> <%@ Register Tag