嵌套多行 lambda 函数作为 LINQ Select 的参数导致错误
我尝试在 VB.NET 中使用嵌套多行 lambda Function
并收到错误。这是我的代码的样子:
cartItems = cartItems.Select(Function(ci) New With {.CartItem = ci, .Discount = discountItems.FirstOrDefault(Function(di) di.SKU = ci.SKU)})
.Select(Function(k)
If k.Discount Is Not Nothing Then
k.CartItem.Discount = minNumberOfItemsDiscounted * k.Discount.DiscountAmount
End If
Return k.CartItem
End Function)
这是很长的错误消息:
Error 1 Overload resolution failed because no accessible 'Select' can be called with these arguments:
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Nested function does not have a signature that is compatible with delegate 'System.Func(Of <anonymous type>, Integer, TResult)'.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': 'Is' operator does not accept operands of type 'Integer'. Operands must be reference or nullable types.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error. C:\_Dev Projects\CMS2000\Components\NET\HBCatalogPromo\CatalogPromotion\CatalogPromotion.ConsoleTest\Module1.vb 88 21 CatalogPromotion.ConsoleTest
感觉我的语法有问题,因为我通过在可能的情况下将 Functions
行折叠到一行来修复其他行。但是,在这种情况下我不能这样做。
I'm trying to use a nested multi-line lambda Function
in VB.NET and am getting an error. Here's what my code looks like:
cartItems = cartItems.Select(Function(ci) New With {.CartItem = ci, .Discount = discountItems.FirstOrDefault(Function(di) di.SKU = ci.SKU)})
.Select(Function(k)
If k.Discount Is Not Nothing Then
k.CartItem.Discount = minNumberOfItemsDiscounted * k.Discount.DiscountAmount
End If
Return k.CartItem
End Function)
And here's the long error message:
Error 1 Overload resolution failed because no accessible 'Select' can be called with these arguments:
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Nested function does not have a signature that is compatible with delegate 'System.Func(Of <anonymous type>, Integer, TResult)'.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, Integer, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': 'Is' operator does not accept operands of type 'Integer'. Operands must be reference or nullable types.
Extension method 'Public Function Select(Of TResult)(selector As System.Func(Of <anonymous type>, TResult)) As System.Collections.Generic.IEnumerable(Of TResult)' defined in 'System.Linq.Enumerable': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error. C:\_Dev Projects\CMS2000\Components\NET\HBCatalogPromo\CatalogPromotion\CatalogPromotion.ConsoleTest\Module1.vb 88 21 CatalogPromotion.ConsoleTest
It feels like I have something wrong with my syntax because I've fixed other lines by collapsing in line Functions
on to one line when possible. However, I can't do that in this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的选择会抛出异常,因为由于您使用了匿名类型,编译器无法确定适当的类型。
话虽这么说,一般来说,使用 Select() 运行会导致副作用的代码(在本例中就是这样做的)是一个坏主意。
在这种情况下,我个人会放弃在单个 LINQ 语句中执行此操作。在我看来,LINQ 导致事情变得比应有的更加复杂。在这种情况下,我的偏好是创建一个函数来执行您的逻辑,并返回适当的填充(已知的非匿名类型)。然后,您可以将 LINQ 语句重构为单个 Select,该 Select 返回您的已知类型。
这将避免潜在的副作用,因为您可以在方法中构造该类型的新实例,并简化代码(包括通过将逻辑重构为在单个“实例”上工作的单独方法来使其更易于测试) ”)。
Your select is throwing because the compiler can't determine the appropriate type due to your usage of a anonymous type.
That being said, it's a bad idea, in general, to use Select() to run code that causes a side effect, which you're doing in this case.
I would, personally, abandon doing this in a single LINQ statement, in this instance. The LINQ is, in my opinion, causing this to be more complex than it ought to be. My preference, in a case like this, would be to make a single function that does your logic, and returns an appropriate, filled in (known, non-anonymous type). You could then just refactor your LINQ statement into a single Select which returns your known type.
This would avoid the potential side effects, since you could construct a new instance of the type in the method, and simplify the code (including making it much more easily testable, by refactoring the logic into a separate method that worked on a single "instance").
Reactive Extension .NET 的 Do() 扩展方法可能是如果您只期待副作用,那么这是一个不错的选择。之后,您可以正常使用 Select() 投影方法。
Reactive Extension .NET's Do() extension method might be a good candidate if you expecting only side-effect. After that, you can use Select() projection method as normal.