Так сказать, у меня есть класс Student с одним свойством, int Age
. Теперь, если у меня есть List<Student> students
, как проверить, равен ли возраст всех учеников в списке?
Как проверить, является ли значение свойства для каждого члена списка одинаковым
Ответ 1
Вы можете проверить с помощью метода All
, предположительно, у вашего списка есть ученики:
var firstStudent = students.First();
students.All(s => s.Age == firstStudent.Age);
Ответ 2
Если вы хотите сделать это в одном запросе, а не в двух (что обычно плохо),
bool allAgesAreTheSame = (students.Select(s => s.Age).Distinct().Count() < 2);
сделает это за вас.
Это также вернет true в тривиальном случае, когда у вас нет учеников вообще, вместо того, чтобы бросать исключение. (Вместо < 2
вы можете сделать == 1
, чтобы вместо этого возвращать значение false в тривиальном случае.)
Ответ 3
Если у студентов может быть 0 элементов, вы можете сделать это:
var firstStudent = students.FirstOrDefault();
var areSame =students.All(s => s.Age == firstStudent.Age);
Ответ 4
Просто случайный ответ - не уверен, что я сделаю это так на самом деле, но это будет жестоко эффективным:
- будет использовать типизированные итераторы, если доступна утиная печать (в отличие от LINQ, которая не будет) - и обратите внимание, что
List<T>
делает предлагать итераторы с утиным текстом - нет двойных итераций
- нет ошибок и т.д. для пустых последовательностей
- нет делегатов, контекстов захвата и т.д.
- и т.д.
код:
using(var iter = students.GetEnumerator()) // a List<T>.Enumerator struct
{
if(!iter.MoveNext()) return true; // or false, as you define for "empty"
int age = iter.Current.Age;
while(iter.MoveNext())
if(iter.Current.Age != age)
return false;
return true;
}
Ответ 5
Если вы не можете использовать linq, вы можете всегда зацикливать всех студентов:
private bool sameAge (List<Student> students)
{
int auxAge = students.Count > 0? students[0].Age : 0;
foreach (Student stu in students)
{
if (stu.Age != auxAge)
return false;
}
return true;
}
Ответ 6
Если вам просто нужно это проверить один раз, то наилучшим решением будет отмеченный ответ. Чтобы использовать его несколько раз в вашем коде, просто напишите статическое расширение, чтобы проверить равенство свойства:
public static bool GetIdenticProperty<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> predicate)
{
IEnumerable<TSource> enumerable = source as IList<TSource> ?? source.ToList();
if ((!enumerable.Any()) || (enumerable.Count() == 1))
return true; // or false if you prefere
var firstItem = enumerable.First();
bool allSame = enumerable.All(i => Equals(predicate(i), predicate(firstItem)));
return allSame;
}
Если вы хотите использовать значение свойства позже, давайте вернем это значение:
public static TKey GetIdenticProperty<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> predicate)
{
IEnumerable<TSource> enumerable = source as IList<TSource> ?? source.ToList();
if (!enumerable.Any())
return default(TKey);
var firstItem = enumerable.First();
bool allSame = enumerable.All(i => Equals(predicate(i), predicate(firstItem)));
return allSame ? predicate(firstItem) : default(TKey);
}
Но используя этот код, вы должны проверить погоду, значение returnd равно null
или default(TKey)
, относящееся к типу свойства.