У меня есть лямбда-выражение, которое находит в форме все метки, содержащие имя определенного метода (метки создаются динамически и содержат префикс и имя метода). Выражение удаляет префикс и оценивает, соответствует ли то, что осталось, имени метода. Все работало нормально, пока я не наткнулся на метод, возвращающий только одну метку. Когда он попадает в эту строку:
var labels = methodLabels
.Where(t => t.Name.Remove(0, t.Name.IndexOf(d.Name)) == d.Name)
.ToList();
Выдает исключение "Счетчик не может быть меньше нуля. Имя параметра: count". Однако, если я изменяю ToList() на FirstOrDefault(), он работает нормально и возвращает правильную метку. Это в цикле foreach:
foreach (var d in remainingMethods)
{
var labels = methodLabels.Where(t => t.Name.Remove(0, t.Name.IndexOf(d.Name)) == d.Name).ToList();
foreach (var l in labels)
Я не нахожу ничего в Интернете, что решает мою проблему. Если кто-нибудь знает, почему это происходит, или может помочь с обходным путем, я был бы признателен. Я не могу просто изменить его на FirstOrDefault(), если запрос возвращает более одной записи. Любая помощь приветствуется.
Ваше исключение "Count cannot be less than zero. Parameter name: count".
относится ко второму параметру в методе Строка.Удалить. IndexOf
, скорее всего, возвращает отрицательное значение 1, если имя метода не найдено в вашей строке. Поскольку использование удаления в лямбде на самом деле не позволяет вам вернуть список с удаленным префиксом, вы можете просто использовать String.Contains
. Однако, если это слишком широко и может возвращать ложные срабатывания, вы можете обновить текущую проверку, чтобы учесть, когда имя метода не найдено.
var labels = methodLabels
.Where(t => t.Name.Remove(0, Math.Max(0,t.Name.IndexOf(d.Name))) == d.Name)
.ToList();
Не может использовать содержит. Это то, что у нас было сначала, и это были дополнительные услуги. Я попробую ваше предложение и посмотрю, сработает ли оно. Звучит разумно. Большое спасибо за помощь.
КЛАССНО! Работал как шарм! Бесконечно благодарен!
Я предполагаю, что ошибка возникает из-за вызова метода Remove
, потому что метод IndexOf
возвращает -1
для одного из элементов в methodLabels
, поскольку его Name
нет содержит значение в d.Name
.
Когда вы делаете FirstOrDefault
, как указано в Камило Теревинто, он вернет первый, который соответствует вашему предикату Where
, и прекратит обработку следующих элементов в methodLabels
; но когда вы это сделаете ToList
, он превысит все элементов в methodLabels
, и один из элементов вызовет появление ошибки.
См. документацию для String.Remove
.
ExceptionsArgumentOutOfRangeException Either
startIndex
orcount
is less than zero.
Это работает?
var labels = methodLabels
.Where(t => t.Name.Remove(0, Math.Max(0, t.Name.IndexOf(d.Name))) == d.Name)
.ToList();
Когда вы используете
FirstOrDefault
, перечисление оценивается только до тех пор, пока не будет найдено первое совпадение. ЕслиToList
выдает это исключение, тоmethodLabels
имеет как минимум 2 элемента, и один из них возвращает отрицательное значение дляt.Name.IndexOf(d.Name)