Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表达式树lambda不能包含null传播运算符_C#_Linq_Null Coalescing Operator - Fatal编程技术网

C# 表达式树lambda不能包含null传播运算符

C# 表达式树lambda不能包含null传播运算符,c#,linq,null-coalescing-operator,C#,Linq,Null Coalescing Operator,问题:行price=co?.price??0,在下面的代码中给出了上述错误。但是如果我从公司?中删除?,效果会很好。我试图跟踪他们在行上使用?的位置,选择新的{person.FirstName,PetName=subpet?.Name??String.Empty}所以,我似乎需要了解何时将?与?一起使用,何时不使用 错误: 表达式树lambda不能包含null传播运算符 公共类CustomerOrdersModelView { 公共字符串CustomerID{get;set;} 公共整数FY{g

问题:行
price=co?.price??0,
在下面的代码中给出了上述错误。但是如果我从
公司?
中删除
,效果会很好。我试图跟踪他们在
上使用
的位置,选择新的{person.FirstName,PetName=subpet?.Name??String.Empty}
所以,我似乎需要了解何时将
一起使用,何时不使用

错误

表达式树lambda不能包含null传播运算符

公共类CustomerOrdersModelView
{
公共字符串CustomerID{get;set;}
公共整数FY{get;set;}
公开浮动?价格{get;set;}
....
....
}
公共异步任务ProductAnnualReport(字符串rpt)
{
var qry=来自c in_context.Customers
在上下文中加入ord
c.CustomerID等于ord.CustomerID到co
来自m in co.DefaultIfEmpty()
选择新CustomerOrdersModelView
{
CustomerID=c.CustomerID,
FY=c.FY,
价格=co?,价格=0,
....
....
};
....
....
}

您引用的示例使用LINQ to对象,其中查询中的隐式lambda表达式转换为委托。。。而您使用的是EF或类似工具,以及
IQueryable
queryies,其中lambda表达式被转换为表达式树。表达式树不支持空条件运算符(或元组)

就按老办法做吧:

price = co == null ? 0 : (co.price ?? 0)

(我相信空合并运算符在表达式树中是可以使用的。)

您链接到的代码使用
列表<代码>列表
实现
IEnumerable
但不实现
IQueryable
。在这种情况下,投影在内存中执行,
?。
工作

您使用的是一些
IQueryable
,其工作原理非常不同。对于
IQueryable
,将创建投影的表示,并且您的LINQ提供程序将决定在运行时如何处理它。出于向后兼容的原因,
?。
不能在此处使用


根据LINQ提供者的不同,您可能能够使用普通的
,但仍然无法获得任何
NullReferenceException

Jon Skeet的答案是正确的,在我的例子中,我对实体类使用了
DateTime
。 当我尝试使用like时

(a.DateProperty == null ? default : a.DateProperty.Date)
我犯了错误

Property 'System.DateTime Date' is not defined for type 'System.Nullable`1[System.DateTime]' (Parameter 'property')
所以我需要为我的实体类和

(a.DateProperty == null ? default : a.DateProperty.Value.Date)

虽然表达式树不支持C#6.0空传播,但我们可以创建一个访问者来修改表达式树以实现安全的空传播,就像操作符所做的那样

公共类NullPropagationVisitor:ExpressionVisitor
{
私有只读布尔递归;
公共NullPropagationVisitor(布尔递归)
{
_递归=递归;
}
受保护的重写表达式访问权限(UnaryExpression propertyAccess)
{
if(propertyAccess.Operator为MemberExpression mem)
回访成员(mem);
if(propertyAccess.Operator为MethodCallExpression满足)
回访方法调用(met);
if(propertyAccess.Operator为ConditionalPression cond)
返回表达式.条件(
测试:条件测试,
Ifrue:MakeNullable(访问(cond.Ifrue)),
ifFalse:MakeNullable(访问(cond.ifFalse));
返回base.visitonary(propertyAccess);
}
受保护的重写表达式VisitMember(MemberExpression propertyAccess)
{
返回Common(propertyAccess.Expression,propertyAccess);
}
受保护的重写表达式VisitMethodCall(MethodCallExpression propertyAccess)
{
if(propertyAccess.Object==null)
返回base.VisitMethodCall(propertyAccess);
返回公共(propertyAccess.Object,propertyAccess);
}
专用块表达式公用(表达式实例、表达式属性访问)
{
var safe=_recursive?base.Visit(实例):实例;
var caller=Expression.Variable(safe.Type,“caller”);
var assign=Expression.assign(调用者,安全);
var acess=MakeNullable(新表达式替换程序(实例,
IsNullableStruct(实例)?调用者:Removenulable(调用者)).Visit(propertyAccess));
var=表达式.条件(
测试:Expression.Equal(调用者,Expression.Constant(null)),
ifTrue:Expression.Constant(null,acess.Type),
如果是:访问);
返回表达式.Block(
类型:acess.type,
变量:新[]
{
呼叫者
},
表达式:新表达式[]
{
分配
三元,
});
}
私有静态表达式MakeNullable(表达式ex)
{
if(IsNullable(ex))
退换货;
返回表达式.Convert(ex,typeof(null).MakeGenericType(ex.Type));
}
私有静态bool可为空(表达式ex)
{
return!ex.Type.IsValueType | |(Nullable.GetUnderlyingType(ex.Type)!=null);
}
私有静态bool IsNullableStruct(表达式ex)
{
返回ex.Type.IsValueType&(null.getUnderlineType(ex.Type)!=null);
}
私有静态表达式可移除(表达式ex)
{
if(IsNullableStruct(ex))
返回表达式.Convert(ex,ex.Type.GenericTypeArguments[0]);
退换货;
}
私有类ExpressionReplacer:ExpressionVisitor
{
私有只读表达式_oldEx;
私有只读表达式_newEx;
内部表达式替换程序(表达式oldEx、表达式newEx)
{
_oldEx=oldEx;
(a.DateProperty == null ? default : a.DateProperty.Value.Date)