我正在尝试在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
中折叠到一行来修复其他行。但是,在这种情况下,我无法做到这一点。
答案 0 :(得分:1)
由于您使用了匿名类型,编译器无法确定合适的类型,因此您的选择正在抛出。
话虽如此,一般来说,使用Select()来运行导致副作用的代码是个坏主意,在这种情况下你正在做。
在本例中,我个人会放弃在单个LINQ语句中执行此操作。在我看来,LINQ导致它比它应该更复杂。在这种情况下,我的偏好是创建一个能够完成逻辑的函数,并返回一个适当的,填充的(已知的,非匿名类型)。然后,您可以将LINQ语句重构为单个Select,返回已知类型。
这样可以避免潜在的副作用,因为你可以在方法中构造一个新类型的实例,并简化代码(包括使代码更容易测试,通过将逻辑重构为一个单独的方法来处理单个“实例”)。
答案 1 :(得分:0)
Reactive Extension .NET如果您只期望副作用,那么Do()扩展方法可能是一个很好的选择。之后,您可以正常使用Select()投影方法。