嵌套多行 lambda 函数作为 LINQ Select 的参数导致错误

发布于 2024-09-07 07:55:08 字数 2240 浏览 4 评论 0原文

我尝试在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放手` 2024-09-14 07:55:08

您的选择会抛出异常,因为由于您使用了匿名类型,编译器无法确定适当的类型。

话虽这么说,一般来说,使用 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").

鯉魚旗 2024-09-14 07:55:08

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文