没有合适的资源?快使用搜索试试~ 我知道了~
1、表达式目录树 表达式目录树,在C#中是Expression来定义的,它是一种语法树,或者说是一种数据结构。其主要用于存储需要计算、运算的一种结构,它只提供存储功能,不进行运算。通常Expression是配合Lambda一起使用,lambda可以是匿名方法。Expression可以动态创建。 声明一个lambda表达式,其中可以指明类型,也可以是匿名方法: //Func<int> func = new Func<int>((m, n) => m * n + 2); Func<int> func = (m, n) => m
资源推荐
资源详情
资源评论
C#表达式目录树示例详解表达式目录树示例详解
1、表达式目录树、表达式目录树
表达式目录树,在C#中是Expression来定义的,它是一种语法树,或者说是一种数据结构。其主要用于存储需要计算、
运算的一种结构,它只提供存储功能,不进行运算。通常Expression是配合Lambda一起使用,lambda可以是匿名方法。
Expression可以动态创建。
声明一个lambda表达式,其中可以指明类型,也可以是匿名方法:
//Func<int, int, int> func = new Func<int, int, int>((m, n) => m * n + 2);
Func<int, int, int> func = (m, n) => m * n + 2;
上述代码可以使用Expression来定义:
Expression<Func<int, int, int>> exp = (m, n) => m * n + 2;//lambda表达式声明表达式目录树
Expression的方法体只能是一个整体,不能具有花括号,以下代码是不允许的:
Expression<Func<int, int, int>> exp1 = (m, n) =>//方法体只能一体
{
return m * n + 2;
};
上述func和exp执行结果相同:
int iResult1 = func.Invoke(3, 2);
int iResult2 = exp.Compile().Invoke(3, 2);
2、构建表达式目录树、构建表达式目录树
上述表达式示例可以通过Expression来自主构建,把m、n定义为ParameterExpression参数,把2定义为常数表达式
ConstantExpression,使用Expression的静态方法,表示乘和加:
ParameterExpression parameterLeft = Expression.Parameter(typeof(int), "m");//定义参数
ParameterExpression parameterRight = Expression.Parameter(typeof(int), "n");//定义参数
BinaryExpression binaryMultiply = Expression.Multiply(parameterLeft, parameterRight);//组建第一步的乘法
ConstantExpression constant = Expression.Constant(2, typeof(int)); //定义常数参数
BinaryExpression binaryAdd = Expression.Add(binaryMultiply, constant);//组建第二步的加法
var expression = Expression.Lambda<Func<int, int, int>>(binaryAdd, parameterLeft, parameterRight);//构建表达式
var func = expression.Compile(); //编译为lambda表达式
int iResult3 = func(3, 2);
int iResult4 = expression.Compile().Invoke(3, 2);
int iResult5 = expression.Compile()(3, 2);
自主构建Expression是,参数名称的定义,可以不是m、n,可以是其他的a、b或者x、y。
如何构建一个复杂的表达式目录树?需要使用到Expression中更多的方法、属性、扩展方法等。首先定义一个类:
public class People
{
public int Age { get; set; }
public string Name { get; set; }
public int Id;
}
基于上面的类,构建表达式: Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals(“5”);
这个示例中,使用到了int自身的ToString()方法,还使用到了字符串的Equals方法。构建过程如下:
//以下表达式目录树实现lambda的表达式
Expression<Func<People, bool>> lambda = x => x.Id.ToString().Equals("5");
//声明一个参数对象
ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x");
//查找字段, 并绑定访问参数对象字段(属性)的方法:x.Id
MemberExpression member = Expression.Field(parameterExpression, typeof(People).GetField("Id"));
//以上可以用这个代替
var temp =Expression.PropertyOrField(parameterExpression, "Id");
//调用字段的ToString方法:x.Id.ToString()
MethodCallExpression method = Expression.Call(member, typeof(int).GetMethod("ToString", new Type[] { }), new Expression[0]);
//调用字符串的Equals方法:x.Id.ToString().Equals("5")
MethodCallExpression methodEquals = Expression.Call(method, typeof(string).GetMethod("Equals", new Type[] { typeof(string) }), new Expression[] {
Expression.Constant("5", typeof(string))//与常量进行比较,也可以是参数
});
//创建目录树表达式
ar expression = Expression.Lambda<Func<People, bool>>(methodEquals, new ParameterExpression[] {parameterExpression });
bool bResult = expression.Compile().Invoke(new People()
{
Id = 5,
Name = "Nigle",
Age = 31
});
3、使用、使用Expression来进行不同对象的相同名字的属性映射来进行不同对象的相同名字的属性映射
前面构建了类People,现在我们构建一个新的类PeopleCopy:
public class PeopleCopy
{
public int Age { get; set; }
public string Name { get; set; }
public int Id;
}
现在声明一个People对象,然后对People对象的数据进行拷贝到PeopleCopy新对象中去,直接硬编码的方式:
1. 硬编码硬编码
People people = new People()
{
Id = 11,
Name = "Nigle",
Age = 31
};
PeopleCopy peopleCopy = new PeopleCopy()
{
Id = people.Id,
Name = people.Name,
Age = people.Age
};
如果这样编写,对于属性或者字段比较多的类,在拷贝时,我们需要编写很多次赋值,代码也会很长。此时,我们能想到
的是通过反射的方式进行拷贝:
2. 反射拷贝反射拷贝
public static TOut Trans<TIn, TOut>(TIn tIn)
{
TOut tOut = Activator.CreateInstance<TOut>();
foreach (var itemOut in tOut.GetType().GetProperties())
{
foreach (var itemIn in tIn.GetType().GetProperties())
{
if (itemOut.Name.Equals(itemIn.Name))
{
itemOut.SetValue(tOut, itemIn.GetValue(tIn));
break;
}
}
}
foreach (var itemOut in tOut.GetType().GetFields())
{
foreach (var itemIn in tIn.GetType().GetFields())
{
if (itemOut.Name.Equals(itemIn.Name))
{
itemOut.SetValue(tOut, itemIn.GetValue(tIn));
break;
}
}
}
return tOut;
}
通过反射,我们可以通过输出类型的属性或者字段去查找原类型对应的属性和字段,然后获取值,并设置值的方式进行赋
值拷贝。除此之外,我们还能想到的是深克隆的序列化方式,进行反序列化数据:
剩余8页未读,继续阅读
资源评论
weixin_38516491
- 粉丝: 6
- 资源: 950
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- traitlets-4.3.3-py2.py3-none-any.whl.rar
- traitlets-5.3.0-py3-none-any.whl.rar
- tornado-6.1-cp311-cp311-win32.whl.rar
- traits-5.0.0-cp34-cp34m-win32.whl.rar
- traits-5.0.0-cp34-cp34m-win_amd64.whl.rar
- traits-4.6.0-cp34-cp34m-win32.whl.rar
- traits-4.6.0-cp34-cp34m-win_amd64.whl.rar
- traits-5.2.0-cp27-cp27m-win32.whl.rar
- traits-5.2.0-cp27-cp27m-win_amd64.whl.rar
- traits-5.2.0-cp35-cp35m-win_amd64.whl.rar
- traits-6.1.1-cp36-cp36m-win_amd64.whl.rar
- traits-5.2.0-cp35-cp35m-win32.whl.rar
- ErrDataUnderflow(解决方案).md
- ErrUninitializedVariable(解决方案).md
- ErrUnsupportedOperation(解决方案).md
- traits-6.1.1-cp36-cp36m-win32.whl.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功