表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数
2021-02-02 00:29
标签:enum 访问 式表 call ida ons 实践 其他 静态 目录 C# 表达式树中,定义一个变量,使用 创建变量结点的方法有两种, 两种方式都是生成 对于使用定义: 先看第一种 从代码来看,没有区别。 再看看具有两个参数的重载 如你所见,两者只有一个 allowByRef 出现了区别,Paramter 允许 Ref, Variable 不允许。 笔者在官方文档和其他作者文章上,都没有找到具体区别是啥,去 stackoverflow 搜索和查看源代码后,确定他们的区别在于 Variable 不能使用 ref 类型。 从字面意思来看,声明一个变量,应该用 无论值类型还是引用类型,都是这样子定义。 访问变量或类型的属性,使用 访问变量/类型的属性或字段,使用 访问变量或类型的方法,使用 访问属性字段和方法 他们都返回一个 MemberExpression类型。 使用上,根据实例化/不实例化,有个小区别,上面说了变量或类型。 意思是,已经定义的值类型或实例化的引用类型,是变量; 类型,就是指引用类型,不需要实例化的静态类型或者静态属性字段/方法。 上面的解释不太严谨,下面示例会慢慢解释。 使用 Console 是一个静态类型,Console.Title 可以获取编译器程序的实际位置。 使用表达式树表达如下 因为调用的是静态类型的属性,所以第一个参数为空。 第二个参数是一个 PropertyInfo 类型。 C#代码如下 在表达式树,调用实例的属性 除了 Expression.Property() ,其他的方式请自行测试,这里不再赘述。 使用 以 Console 为例,调用 WriteLine() 方法 Expression.Call() 的重载方法比较多,常用的重载方法是 因为要调用静态类型的函数,所以第一个 instance 为空(instance英文意思是实例)。 第二个 method 是要调用的重载方法。 最后一个 arguments 是传入的参数。 写一个类 调用实例的 Printf() 方法 表达式表达如下 注意的是, 上面的方式,是通过外界实例化传入里面的,后面会说如何在表达式内实例化。 引用类型的实例化,使用 new ,然后选择调用合适的构造函数、设置属性的值。 那么,根据上面的步骤,我们分开讨论。 使用 他有五个重载,有两种常用重载: 依然使用上面的 Test 类型 默认没有参数的构造函数,或者只有一个构造函数,像上面这样调用。 如果像指定一个构造函数,可以 这里就不详细说了。 实例化一个构造函数的同时,可以给属性赋值。 两种重载是一样的。 我们将 Test 类改成 然后 表示调用构造函数并初始化新对象的一个或多个成员。 如果实例化一个类,可以使用 如果要在实例化时给成员赋值 实例化一个类型,调用构造函数、给成员赋值,示例代码如下 将 Test 类,改成这样 Test 类已经是一个泛型类,表达式实例化示例 集合类型使用 创建集合类型,需要使用到 ElementInit 表示 IEnumerable集合的单个元素的初始值设定项。 ListInit 初始化一个集合。 C# 中,集合都实现了 IEnumerable,集合都具有 Add 扥方法或属性。 使用 C# 初始化一个集合并且添加元素,可以这样 而在表达式树里面,是通过 ElementInit 调用 Add 方法初始化/添加元素的。 示例 示例 表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数 标签:enum 访问 式表 call ida ons 实践 其他 静态 原文地址:https://www.cnblogs.com/whuanle/p/11569083.html
表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数
一,定义变量
ParameterExpression
。Expression.Parameter()
Expression.Variable()
// 另外,定义一个常量可以使用 Expression.Constant()。
ParameterExpression
类型 Parameter()
和 Variable()
都具有两个重载。他们创建一个 ParameterExpression节点,该节点可用于标识表达式树中的参数或变量。Expression.Variable
用于在块内声明局部变量。Expression.Parameter
用于声明输入值的参数。 public static ParameterExpression Parameter(Type type)
{
return Parameter(type, name: null);
}
public static ParameterExpression Variable(Type type)
{
return Variable(type, name: null);
}
public static ParameterExpression Parameter(Type type, string name)
{
Validate(type, allowByRef: true);
bool byref = type.IsByRef;
if (byref)
{
type = type.GetElementType();
}
return ParameterExpression.Make(type, name, byref);
}
public static ParameterExpression Variable(Type type, string name)
{
Validate(type, allowByRef: false);
return ParameterExpression.Make(type, name, isByRef: false);
}
Expression.Variable
, 函数的传入参数应该使用Expression.Parameter
。二,访问变量/类型的属性字段和方法
Expression.Property()
Expression.PropertyOrField()
Expression.Call()
Expression.MakeMemberAccess
1. 访问属性
Expression.Property()
或 Expression.PropertyOrField()
调用属性。调用静态类型属性
Console.WriteLine(Console.Title);
MemberExpression member = Expression.Property(null, typeof(Console).GetProperty("Title"));
Expression
调用实例属性/字段
List
ParameterExpression a = Expression.Parameter(typeof(List
2. 调用函数
Expression.Call()
可以调用一个静态类型的函数或者实例的函数。调用静态类型的函数
Console.WriteLine("调用WriteLine方法");
MethodCallExpression method = Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
Expression.Constant("调用WriteLine方法"));
Expression lambda = Expression.Lambda(method);
lambda.Compile()();
Console.ReadKey();
public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments)
调用实例的函数
public class Test
{
public void Print(string info)
{
Console.WriteLine(info);
}
}
Test test = new Test();
test.Print("打印出来");
Console.ReadKey();
ParameterExpression a = Expression.Variable(typeof(Test), "test");
MethodCallExpression method = Expression.Call(
a,
typeof(Test).GetMethod("Print", new Type[] { typeof(string) }),
Expression.Constant("打印出来")
);
Expression
Expression.Variable(typeof(Test), "test");
仅定义了一个变量,还没有初始化/赋值。对于引用类型来说,需要实例化。三,实例化引用类型
new
Expression.New()
来调用一个类型的构造函数。 public static NewExpression New(ConstructorInfo constructor);
public static NewExpression New(Type type);
NewExpression newA = Expression.New(typeof(Test));
NewExpression newA = Expression.New(typeof(Test).GetConstructor(xxxxxx));
给属性赋值
public static MemberInitExpression MemberInit(NewExpression newExpression, IEnumerable
public class Test
{
public int sample { get; set; }
public void Print(string info)
{
Console.WriteLine(info);
}
}
var binding = Expression.Bind(
typeof(Test).GetMember("sample")[0],
Expression.Constant(10)
);
创建引用类型
Expression.MemberInit()
NewExpression newA = Expression.New(typeof(Test));
MemberInitExpression test = Expression.MemberInit(newA,
new List
NewExpression newA = Expression.New(typeof(Test));
// 给 Test 类型的一个成员赋值
var binding = Expression.Bind(
typeof(Test).GetMember("sample")[0],Expression.Constant(10));
MemberInitExpression test = Expression.MemberInit(newA,
new List
示例
// 调用构造函数
NewExpression newA = Expression.New(typeof(Test));
// 给 Test 类型的一个成员赋值
var binding = Expression.Bind(
typeof(Test).GetMember("sample")[0], Expression.Constant(10));
// 实例化一个类型
MemberInitExpression test = Expression.MemberInit(newA,
new List
四,实例化泛型类型于调用
public class Test
static void Main(string[] args)
{
RunExpression
五,定义集合变量、初始化、添加元素
ListInitExpression
表示。 List
MethodInfo listAdd = typeof(List
MethodInfo listAdd = typeof(List
文章标题:表达式树练习实践:C#值类型、引用类型、泛型、集合、调用函数
文章链接:http://soscw.com/index.php/essay/49731.html