当前位置: 首页 > 编程语言 > C#

如何从字符串创建表达式树-lambda以获得深层属性共享

时间:2023-04-11 01:59:46 C#

如何从字符串创建表达式树/lambda给定字符串:“Person.Address.Postcode”I希望能够在Person的实例上获取/设置此邮政编码属性。我怎样才能做到这一点?我的想法是将字符串拆分为“。'然后遍历这些部分,寻找先前类型的属性,并构建一个看起来像的表达式树(为伪语法道歉):(person=>person.Address)address=>address.Postcode我是实际上创建表达式树我遇到了麻烦!如果这是最好的方法,有人可以建议怎么做,还是有更简单的选择?谢谢安德鲁publicclassPerson{publicintAge{get;放;}公共字符串名称{得到;放;}公共地址地址{get;放;}publicPerson(){Address=newAddress();}}publicclassAddress{publicstringPostcode{get;放;为什么不使用递归?比如:setProperyValue(obj,propertyName,value){head,tail=propertyName.SplitByDotToHeadAndTail();//Person.Address.Postcode=>{head=Person,tail=Address.Postcode}if(tail.Length==0)setPropertyValueUsingReflection(obj,head,value);否则setPropertyValue(getPropertyValueUsingReflection(obj,head),tail,value);//递归}听起来你是在用正则反射排序,但是forinfo,构建嵌套属性表达式的代码和这个order-by的代码非常相似。请注意,要设置值,您需要在属性上使用GetSetMethod()并调用它-没有用于在构造后分配值的内置表达式(尽管在4.0中支持)。(编辑)像这样:usingSystem;使用System.Linq;使用System.Linq.Expressions;使用System.Reflection;classFoo{publicFoo(){Bar=newBar();}publicBarBar{get;私有集;}}classBar{publicstringName{get;set;}}staticclassProgram{staticvoidMain(){Foofoo=newFoo();varsetValue=BuildSet("Bar.Name");vargetValue=BuildGet("Bar.Name");设置值(foo,“abc”);Console.WriteLine(getValue(foo));}staticActionBuildSet(stringproperty){string[]props=property.Split('.');类型类型=typeof(T);ParameterExpressionarg=Expression.Parameter(type,"x");ParameterExpressionvalArg=Expression.Parameter(typeof(TValue),"val");表达式expr=arg;foreach(stringpropinprops.Take(props.Length-1)){//使用反射(不是ComponentModel)来镜像LINQPropertyInfopi=type.GetProperty(prop);expr=Expression.Property(expr,pi);type=pi.PropertyType;}//最终属性集...PropertyInfofinalProp=type.GetProperty(props.Last());MethodInfosetter=finalProp.GetSetMethod();expr=Expression.Call(expr,setter,valArg);返回Expression.Lambda>(expr,arg,valArg).Compile();}staticFuncBuildGet(stringproperty){string[]props=property.Split('.');类型类型=typeof(T);ParameterExpressionarg=Expression.Parameter(type,"x");表达式expr=arg;foreach(stringpropinprops){//使用反射(不是ComponentModel)来镜像LINQPropertyInfopi=type.GetProperty(prop);expr=Expression.Property(expr,pi);type=pi.PropertyType;}returnExpression.Lambda>(expr,arg).Compile();如果有人对简单反射方法(这里和这里也有很好的例子)和Marc的表达式构造方法之间的性能权衡感兴趣...我的测试涉及获取相对更深层次的属性(ABCDE)10,000次简单反射:64毫秒表达式build:1684ms显然这是一个非常具体的测试,我没有考虑优化或设置属性,但我认为26倍的性能下降是值得注意的。您希望通过TypeConverter或其他来源提供您自己的PropertyDescriptor。我已经通过从BindingSource派生并通过那里提供信息来实现您为当前项目描述的内容(抱歉,业务,我将分享)。这个想法如下:一旦你有了类型,你需要做的就是为属性的getter和setter创建一些“堆栈”,你可以通过首先遍历类型及其属性的属性树来收集它们,限制深度到指定的级别数,并根据您的数据结构删除循环引用。我正在使用它成功地使用Linq2SQL对象并组合它们的绑定列表:)表达式树以上就是C#学习教程:如何从字符串中为深层属性创建表达式树/lambdas的全部内容,如果对大家有用的话还有我需要了解更多C#学习教程,希望大家多多关注——structtree{charinfo;结构树*rchild;结构树*lchild;};intprec(字符数据);typedef结构树*节点;字符pop_op();节点pop_num();voidpush_op(字符项);节点创建(){返回((节点)malloc(sizeof(节点)));}节点数[20],root=NULL;字符op[20],oprt,ev[20];int=-1,ot=-1,et=-1;main(){节点newnode,item,temp;字符海峡[50];inti,k,p,s,flag=0;printf("输入表达式");scanf("%s",str);printf("n%s",str);for(i=0;str[i]!='';i++){if(isalnum(str[i])){newnode=create();newnode->info=str[i];newnode->lchild=NULL;新节点->rchild=NULL;项目=新节点;push_num(项目);}else{if(ot!=-1)p=prec(op[ot]);否则p=0;k=prec(str[i]);if(k==5){while(k!=1){oprt=pop_op();新节点=创建();新节点->信息=oprt;newnode->rchild=pop_num();newnode->lchild=pop_num();//if(root==NULL)root=newnode;//否则我f((newnode->rchild==root)||(newnode->lchild==root))//root=newnode;push_num(根);k=prec(op[ot]);}oprt=pop_op();}elseif(k==1)push_op(str[i]);else{if(k>p)push_op(str[i]);else{if(krchild=pop_num();newnode->lchild=pop_num();if(root==NULL)root=newnode;elseif((newnode->rchild==root)||(newnode->lchild==root))root=newnode;push_num(newnode);push_op(str[i]);//k=prec(op[ot]);}}}}}printf("n前缀表达式为");preorder(root);printf("n中缀exp是");inorder(root);printf("n后缀表达式是");postorder(root);evaluate();}voidpush_op(charitem){op[++ot]=item;}push_num(nodeitem){num[++nt]=item;}charpop_op(){if(ot!=-1)return(op[ot--]);elsereturn(0);}nodepop_num(){if(nt!=-1)return(num[nt--]);elsereturn(NULL);}intprec(chardata){switch(data){case'(':return(1);中断;case'+':case'-':return(2);break;case'*':case'/':return(3);break;case'^':return(4);break;案件')':返回(5);休息;}}inorder(nodetemp){if(temp!=NULL){inorder(temp->lchild);printf("%c",temp->info);顺序(温度->rchild);}}preorder(nodetemp){if(temp!=NULL){printf("%c",temp->info);预购(温度->lchild);预购(温度->rchild);}}postorder(nodetemp){if(temp!=NULL){postorder(temp->lchild);后序(温度->rchild);printf("%c",temp->info);ev[++et]=temp->信息;}}evaluate(){inti,j=-1,a,b,ch[20];for(i=0;ev[i]!='';i++){if(isalnum(ev[i]))ch[++j]=ev[i]-48;否则{b=ch[j];a=ch[j-1];switch(ev[i]){case'+':ch[--j]=a+b;休息;case'-':ch[--j]=ab;休息;case'*':ch[--j]=a*b;;case'/':ch[--j]=a/b;休息;}}}printf("nValue=%d",ch[0]);}本文收集自网络,不代表立场,如有侵权请点右联系管理员删除。如需转载请注明出处: