У меня есть следующий оператор LINQ в VB:
Dim query As List(Of RepresentativeCase)
query = (From w In Me.RepresentativeCases
Where w.Active = True
Group w By w.PublicSubType, w.LawArea Into g = Group
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
Select g.First()
).ToList()
Я пытаюсь преобразовать в С# и имею проблемы. Я получил следующее, но оно не компилируется:
List<RepresentativeCase> query = (
from w in this.RepresentativeCases
where w.Active == true
group w by new { w.PublicSubType, w.LawArea} into g
let PublicSubType = g.Key.PublicSubType
let LawArea = g.Key.LawArea
where g.Count(x => x.PublicSubType.Distinct().Count()) > 100 // breaks here
select g.First()).ToList();
Строка where g.Count(x => x.PublicSubType.Distinct().Count()) > 100
не будет компилироваться. Кроме того, меня смущает Into g = Group
в образце VB — неясно, что он делает.
Что мне не хватает?
Включите Option Strict On
в VB, и там он тоже не скомпилируется, как должен.
@Flydog57 i.imgur.com/s808bPq.png
@GSerg Верно, но как преобразовать его в C#?
Исправьте ошибку в VB, чтобы она компилировалась с параметром Option Strict On, зеркально отразите ее в C#.
Просто вопрос стиля, Где w.Active = True может быть Где w.Active
В этой строке:
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
Внешний метод .Count()
ожидает лямбду, которая возвращает логическое значение, где результат сообщает .Count()
, следует ли включать этот элемент в конечный результат. Но у вас есть это:
Function(x) x.PublicSubType.Distinct.Count
Результатом вышеуказанной функции является целое число, а не логическое значение. Кроме того, вы должны написать это (вероятно) так:
Function(x) x.PublicSubType.Distinct().Count()
По-прежнему допустимо опускать круглые скобки при вызове методов в VB.Net, но это делается для обратной совместимости со старым кодом и не рекомендуется в других ситуациях.
Я не уверен, что здесь делает код VB, но с разумной конфигурацией, которая также не будет компилироваться в VB. То, что у вас есть, ненормально, тем более, что у VB есть некоторые странные идеи о том, какие целочисленные значения могут отображаться в логические значения true и false.
Я не думаю, что эта последняя ссылка актуальна, потому что это больше о преобразовании Boolean
в Integer
, чем Integer
в Boolean
. CBool(1)
, CBool(-1)
, Convert.ToBoolean(1)
и Convert.ToBoolean(-1)
все производят True
. Разница в CInt(True)
и Convert.ToInt32(True)
, которые дают -1 и 1 соответственно.
Этот:
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
будет компилироваться только с Option Strict Off
. Внешний вызов Count
требует делегата, который возвращает Boolean
, но внутренний вызов Count
возвращает Integer
. Это означает, что этот Integer
должен быть неявно преобразован в Boolean
.
Вопрос, который вы должны были задать, заключался в том, как исправить этот VB для компиляции с помощью Option Strict On
, и, чтобы решить это, вы должны учитывать, что на самом деле делает код. На самом деле происходит то, что нулевой счет будет преобразован в False
, а любой другой счет будет преобразован в True
. Это означает, что на самом деле этот код определяет, есть ли какие-либо элементы в списке PublicSubType
. Как правильно это сделать? Методом Any
:
Where g.Count(Function(x) x.PublicSubType.Any()) >= 100
Обратите внимание, что вызов Distinct
бессмыслен, потому что он может изменить количество элементов, но не то, есть ли какие-либо элементы или нет.
Должно быть довольно очевидно, как преобразовать это в С#, но я отвечаю на конкретный вопрос, как задано:
List<RepresentativeCase> query = (
from w in this.RepresentativeCases
where w.Active == true
group w by new { w.PublicSubType, w.LawArea} into g
let PublicSubType = g.Key.PublicSubType
let LawArea = g.Key.LawArea
where g.Count(x => x.PublicSubType.Any()) > 100
select g.First()).ToList();
Какое сообщение об ошибке во время компиляции?