Вложенная многострочная лямбда-функция в качестве параметра для LINQ Select вызывает ошибку - PullRequest
1 голос
/ 29 июня 2010

Я пытаюсь использовать вложенную многострочную лямбду Function в VB.NET и получаю сообщение об ошибке. Вот как выглядит мой код:

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 в одну строку, когда это возможно. Однако я не могу этого сделать в этом случае.

Ответы [ 2 ]

1 голос
/ 29 июня 2010

Ваш выбор выбрасывает, потому что компилятор не может определить подходящий тип из-за использования вами анонимного типа.

При этом, как правило, плохая идея - использовать Select () для запуска кода, вызывающего побочный эффект, который вы делаете в этом случае.

Лично я бы отказался делать это в одном выражении LINQ, в данном случае. По моему мнению, LINQ делает это более сложным, чем должно быть. В таком случае я предпочел бы сделать одну функцию, которая выполняет вашу логику и возвращает соответствующий заполненный (известный, неанонимный тип). Затем вы можете просто реорганизовать ваш оператор LINQ в один Select, который возвращает ваш известный тип.

Это позволит избежать потенциальных побочных эффектов, поскольку вы можете создать новый экземпляр типа в методе и упростить код (в том числе значительно упростить его тестирование) путем рефакторинга логики в отдельный метод, который работал над один "экземпляр").

0 голосов
/ 30 июня 2010

Реактивное расширение .NET метод Do () может быть хорошим кандидатом, если вы ожидаете только побочный эффект. После этого вы можете использовать метод проекции Select () как обычно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...