gpt4 book ai didi

c# - 如何在动态选择中使用表达式创建 "inline if statement"以进行空检查

转载 作者:行者123 更新时间:2023-11-30 22:57:04 24 4
gpt4 key购买 nike

如何在动态选择中使用表达式创建“内联 if 语句”以进行空值检查?

我为一个对象的嵌套属性写了一个动态选择 LINQ 表达式,但是当它为 null 时抛出异常。所以我想检查该属性是否为空,就这么简单!

我的意思是:

X.Where(...)
.Select(X => new Y{
...
Z = X.Titles == null ? "" : [Linq]
...
}).FirstOrDefault();

这是我写的

private static Expression GetLocalizedString(Expression stringExpression, SupportedCulture supportedCulture)
{
var expression = Expression.Parameter(typeof(APILocalizedString), nameof(APILocalizedString));

var prop = Expression.Property(expression, nameof(APILocalizedString.SupportedCulture));
var value = Expression.Constant(supportedCulture);
var condition = Expression.Equal(prop, value);

var where = Expression.Call(
typeof (Enumerable),
nameof(Enumerable.Where),
new Type[] { typeof(APILocalizedString) },
stringExpression,
Expression.Lambda<Func<APILocalizedString, bool>>(condition, expression));

var select = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.Select),
new Type[] { typeof(APILocalizedString), typeof(string) },
where,
Expression.Lambda<Func<APILocalizedString, string>>(
Expression.Property(expression, nameof(APILocalizedString.Text)),
expression
));

var first = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.First),
new Type[] { typeof(APILocalizedString) },
stringExpression);

var defaultIfEmpty = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.DefaultIfEmpty),
new Type[] { typeof(string) },
select,
first);

var firstOrDefault =
Expression.Call(
typeof(Enumerable),
nameof(Enumerable.FirstOrDefault),
new Type[] { typeof(string) },
defaultIfEmpty);


var nullCheck = Expression.Equal(stringExpression, Expression.Constant(null, stringExpression.Type));
var result = Expression.IfThenElse(nullCheck, Expression.Constant(""), firstOrDefault);

return result;
}

这是 GetLocalizedString 生成的内容:

{IIF((X.Titles == null), "", X.Titles.Where(APILocalizedString => (APILocalizedString.SupportedCulture == EN)).DefaultIfEmpty(X.Titles.First()) .Select(APILocalizedString => APILocalizedString.Text).FirstOrDefault())}

选择表达式

... bindings.Add(Expression.Bind(property, GetLocalizedString(Expression.Property(parameter, "Titles"), SupportedCulture.EN))); ...

这是错误信息:

System.ArgumentException: '参数类型不匹配'

选择属性是字符串类型

有什么方法可以创建像 X.Titles == null 这样的表达式吗? "": [Linq] ?

最佳答案

C# 条件 ?: 运算符的等效表达式是 Expression.Condition .同时Expression.IfThenElse您使用的是 C# if then else block 的等价物。

两种方法都返回 ConditionalExpression填充了 TestIfTrueIfFalse 属性。区别在于Condition的结果Type是操作数的类型,而IfThenElsevoid,因此不能用于查询表达式树。

所以你的具体问题的答案是:

var result = Expression.Condition(nullCheck, Expression.Constant(""), firstOrDefault);

附言作为一个侧节点,我从你的代码片段中得到了几个错误,所以我不得不像这样重新排列它以便在上面的行中得到 w/o 错误:

private static Expression GetLocalizedString(Expression stringExpression, SupportedCulture supportedCulture)
{
var expression = Expression.Parameter(typeof(APILocalizedString), nameof(APILocalizedString));

var prop = Expression.Property(expression, nameof(APILocalizedString.SupportedCulture));
var value = Expression.Constant(supportedCulture);
var condition = Expression.Equal(prop, value);

var where = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.Where),
new Type[] { typeof(APILocalizedString) },
stringExpression,
Expression.Lambda<Func<APILocalizedString, bool>>(condition, expression));

var first = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.First),
new Type[] { typeof(APILocalizedString) },
stringExpression);

var defaultIfEmpty = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.DefaultIfEmpty),
new Type[] { typeof(APILocalizedString) },
where,
first);

var select = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.Select),
new Type[] { typeof(APILocalizedString), typeof(string) },
defaultIfEmpty,
Expression.Lambda<Func<APILocalizedString, string>>(
Expression.Property(expression, nameof(APILocalizedString.Text)),
expression
));

var firstOrDefault =
Expression.Call(
typeof(Enumerable),
nameof(Enumerable.FirstOrDefault),
new Type[] { typeof(string) },
select);


var nullCheck = Expression.Equal(stringExpression, Expression.Constant(null, stringExpression.Type));
var result = Expression.Condition(nullCheck, Expression.Constant(""), firstOrDefault);

return result;
}

关于c# - 如何在动态选择中使用表达式创建 "inline if statement"以进行空检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53873765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com