处理 MemberExpression 中的 "convert to object"
Dealing with "convert to object" in a MemberExpression
我有一个 class 看起来像这样:
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
}
我需要这样做:
var memberExpressions = ConvertToMemberExpressions<MyClass>(o => o.Id, o => o.Name);
...
public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
var results = new List<MemberExpression>();
foreach(var methodExpression in methodExpressions)
{
var memberExpression = methodExpression.Body as MemberExpression;
results.Add(memberExpression);
}
return results;
}
问题是,由于 Func<T, object>
(能够同时包含 int
和 string
作为参数),我的方法表达式看起来像这样:{o => Convert(o.Id, Object)}
,其中不是我需要的。我需要达到 o.Id
.
字符串不会发生这种情况:{o => o.Name}
,此处没有转换。
我使用 Func<T,object>
是为了能够利用 Intellisense 并到达 MyClass 的道具。我试过使用 Func<T, dynamic>
,但结果是一样的。
可以使用多个重载来解决:
public static ConvertToMemberExpressions<TClass, T1>(Expression<Func<TClass,T1>>[] methodExpression1)
public static ConvertToMemberExpressions<TClass, T1, T2>(Expression<Func<TClass,T1>>[] methodExpression1, Expression<Func<TClass,T2>>[] methodExpression2)
...
...但这是我想尽可能避免的牺牲。
问题:
是否可以从 o => Convert(o.Id, Object)
构建 o => o.Id
?
只需检查您的 methodExpression.Body
是否为 UnaryExpression
且 NodeType
为 Convert
:
public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
var results = new List<MemberExpression>();
foreach (var methodExpression in methodExpressions)
{
var expr = methodExpression.Body;
if (expr is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert)
{
expr = unaryExpression.Operand;
}
if (expr is MemberExpression memberExpression)
{
results.Add(memberExpression);
}
else
{
throw new ArgumentException($"Unexpected expression type {expr.NodeType}");
}
}
return results;
}
使用表达式时,调试器是你的朋友:
我有一个 class 看起来像这样:
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
}
我需要这样做:
var memberExpressions = ConvertToMemberExpressions<MyClass>(o => o.Id, o => o.Name);
...
public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
var results = new List<MemberExpression>();
foreach(var methodExpression in methodExpressions)
{
var memberExpression = methodExpression.Body as MemberExpression;
results.Add(memberExpression);
}
return results;
}
问题是,由于 Func<T, object>
(能够同时包含 int
和 string
作为参数),我的方法表达式看起来像这样:{o => Convert(o.Id, Object)}
,其中不是我需要的。我需要达到 o.Id
.
字符串不会发生这种情况:{o => o.Name}
,此处没有转换。
我使用 Func<T,object>
是为了能够利用 Intellisense 并到达 MyClass 的道具。我试过使用 Func<T, dynamic>
,但结果是一样的。
可以使用多个重载来解决:
public static ConvertToMemberExpressions<TClass, T1>(Expression<Func<TClass,T1>>[] methodExpression1)
public static ConvertToMemberExpressions<TClass, T1, T2>(Expression<Func<TClass,T1>>[] methodExpression1, Expression<Func<TClass,T2>>[] methodExpression2)
...
...但这是我想尽可能避免的牺牲。
问题:
是否可以从 o => Convert(o.Id, Object)
构建 o => o.Id
?
只需检查您的 methodExpression.Body
是否为 UnaryExpression
且 NodeType
为 Convert
:
public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
var results = new List<MemberExpression>();
foreach (var methodExpression in methodExpressions)
{
var expr = methodExpression.Body;
if (expr is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert)
{
expr = unaryExpression.Operand;
}
if (expr is MemberExpression memberExpression)
{
results.Add(memberExpression);
}
else
{
throw new ArgumentException($"Unexpected expression type {expr.NodeType}");
}
}
return results;
}
使用表达式时,调试器是你的朋友: