系列文章: C# 表达式树及其应用 (Expression 类)
本节继续讲解Expression相关的API, 力争把相关api 都使用简短demo说明一下
- TryFault 创建一个表示 try 块的 TryExpression,该 try 块包含一个 fault 块,但不包含 catch 语句。
//TryFault 创建一个表示 try 块的 TryExpression,该 try 块包含一个 fault 块,但不包含 catch 语句。
void TryFaultSample()
{
TryExpression tryCatchExpr = Expression.TryFault(
Expression.Block(
Expression.Throw(Expression.Constant(new DivideByZeroException())),
Expression.Constant("Try block")
),
Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })!, Expression.Constant("Fault block"))//Finally block |
);
//Expression.Lambda<Func<string>>(tryCatchExpr).Compile()().Dump("TryFault");//TryFault报错未捕捉
}
TryFaultSample();
- TryFinally 创建一个表示 try 块的 TryExpression,该 try 块包含一个 finally 块,但不包含 catch 语句。 同TryFault
//TryFinally 创建一个表示 try 块的 TryExpression,该 try 块包含一个 finally 块,但不包含 catch 语句。 同TryFault
//TryGetActionType 创建一个 Type 对象,它表示具有特定类型参数的泛型 System.Action 委托类型。//TODO
//TryGetFuncType 创建一个 Type 对象,它表示具有特定类型参数的泛型 System.Func 委托类型。 最后一个类型参数指定已创建委托的返回类型。//TODO
- TypeAs 创建一个表示显式引用或装箱转换的 UnaryExpression(如果转换失败,则提供 null)。
//TypeAs 创建一个表示显式引用或装箱转换的 UnaryExpression(如果转换失败,则提供 null)。
void TypeAsSample()
{
UnaryExpression typeAsExpression = Expression.TypeAs(Expression.Constant(3, typeof(int)), typeof(int?));
typeAsExpression.ToString().Dump("TypeAs");//(3 As Nullable`1)
}
TypeAsSample();
- TypeEqual 创建一个比较运行时类型标识的
//TypeEqual 创建一个比较运行时类型标识的 TypeBinaryExpression。//TODO
//TypeIs 创建一个 TypeBinaryExpression。
void TypeIsSample(){
TypeBinaryExpression typeBindaryExpression = Expression.TypeIs(Expression.Constant("www"),typeof(int));
typeBindaryExpression.ToString().Dump("TypeIs");
}
TypeIsSample();
//UnaryPlus 创建一个表示一元正运算的 UnaryExpression。
void UnaryPlusSample(){
UnaryExpression ue = Expression.UnaryPlus(Expression.Constant(1,typeof(int)));
ue.ToString().Dump("UnaryPlus");//+1
}
UnaryPlusSample();
//Unbox 创建一个表示显式取消装箱的 UnaryExpression。//TODO
- Variable 创建一个 ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量。
//Variable 创建一个 ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量。
void VariableSampel()
{
ParameterExpression variableExpr = Expression.Variable(typeof(int), "sampleVar");//the parameter expression is used to create a variable;
BlockExpression addAssignExpr = Expression.Block(
new ParameterExpression[] { variableExpr },
Expression.Assign(variableExpr, Expression.Constant(1)),
Expression.AddAssign(
variableExpr,
Expression.Constant(2)
)
);
addAssignExpr.Expressions.ForEach(p => p.ToString().Dump());//(sampleVar = 1),(sampleVar +=2)
Console.WriteLine(Expression.Lambda<Func<int>>(addAssignExpr).Compile()());//3
}
VariableSampel();
//VisitChildren 简化节点,然后对简化的表达式调用访问者委托。 该方法在节点不可简化时引发异常。//TODO
补充: 前面可能用到的方法和类
/*
* 定义扩展
*/
public static class Utils
{
/// <summary>
/// 扩展IEnumerable ForEach
///<para>遍历IEnumerable 执行action</para>
/// </summary>
public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
using IEnumerator<TSource> enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
TSource current = enumerator.Current;
action(current);
}
}
}
//4. 方法
//Accept(ExpressionVisitor) //调度到此节点类型的特定 Visit 方法。 例如,MethodCallExpression 调用 VisitMethodCall(MethodCallExpression)。
//示例用到的公共test class
public class Person
{
public string Name { get; set; } = null!;
public string GetName() => this.Name;
public string GetOrSetName(string name)
{
if (this.Name == null) this.Name = name;
return this.Name;
}
}
//Add(Expression, Expression, MethodInfo) 创建一个表示不进行溢出检查的算术加法运算的 BinaryExpression。 可指定实现方法。
public class Plus
{
//下面表达式指定加法的实现
public static int AddOne(int a, int b)
{
return a + b + 1;
}
}
//Bind 创建一个表示成员初始化的 MemberAssignment。
public class TestBindMember
{
public int Num { get; set; }
}
//Call 创建一个 MethodCallExpression。
public class SmapleClass
{
public int AddIntegers(int arg1, int arg2)
{
return arg1 + arg2;
}
}
//Field 创建一个表示访问字段的 MemberExpression。
public class TestFieldClass
{
public int num = 10;
}
//ListBind
class TestListBindClass
{
public TestListBindClass()
{
Nums = new List<int>();
}
public List<int> Nums { get; set; }
}
到此这个系列就结束, 有时间的话在将里面的TODO不定时的补充上去, 望各位多提意见多补充, 谢谢...
本文作者:wwmin
微信公众号: DotNet技术说
本文链接:https://www.jianshu.com/p/d789663ffb79
关于博主:评论和私信会在第一时间回复。或者[直接私信]我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,关注点赞, 您的鼓励是博主的最大动力!
网友评论