Можно использовать "группу" + "orderby". См. LINQ 101 для деталей
var list = new List {"a", "b", "a", "c", "a", "b"};
var q = from x in list
group x by x into g
let count = g.Count()
orderby count descending
select new {Value = g.Key, Count = count};
foreach (var x in q)
{
Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}
В ответ на это сообщение (теперь удаленный):
, Если у Вас есть список некоторых пользовательских объектов тогда, необходимо использовать пользовательский компаратор или группа определенным свойством.
Также запрос не может отобразить результат. Покажите нам полный код для получения лучшей справки.
На основе Вашего последнего обновления:
у Вас есть эта строка кода:
group xx by xx into g
, Так как xx является системой пользовательского объекта, не знает, как сравнить один объект с другим. Как я уже записал, необходимо вести компилятор и обеспечить некоторое свойство, которое будет использоваться в сравнении объектов или обеспечит пользовательский компаратор. Вот пример:
Примечание, которое я использую Foo. Имя как ключ - т.е. объекты будет сгруппировано на основе значения [1 118] свойство Name .
существует одна выгода - Вы рассматриваете 2 объекта быть дубликатом на основе их имен, но что относительно идентификатора? В моем примере я просто беру идентификатор первого объекта в группе. Если Ваши объекты имеют различный Ids, это может быть проблема.
//Using extension methods
var q = list.GroupBy(x => x.Name)
.Select(x => new {Count = x.Count(),
Name = x.Key,
ID = x.First().ID})
.OrderByDescending(x => x.Count);
//Using LINQ
var q = from x in list
group x by x.Name into g
let count = g.Count()
orderby count descending
select new {Name = g.Key, Count = count, ID = g.First().ID};
foreach (var x in q)
{
Console.WriteLine("Count: " + x.Count + " Name: " + x.Name + " ID: " + x.ID);
}
Добавьте атрибут Conditional
к методу, например:
[Conditional("DEBUG")]
public void Whatever() {
//...
}
Обратите внимание, что метод должен возвращать void
и не может иметь никаких ] out
параметров; в противном случае было бы невозможно удалить его вызов.
Метод будет скомпилирован в сборку, но CLS-совместимые компиляторы будут отправлять вызовы этому методу только в том случае, если для сборок, которые они компилируют, определена DEBUG. Обратите внимание, что компилятор C ++ несовместим с CLS и всегда будет вызывать вызов.
Кстати, код вызываемого метода остается в сборке - это его вызовы, которые удаляются во время компиляции
Дополнительное тематическое сообщение в блоге: http://blogs.msdn.com/ericlippert/archive/2009/09/10/what-s-the-difference-between-conditional-compilation-and-the-conditional-attribute.aspx
Если вы дизассемблируете класс System.Diagnostics.Debug с помощью Reflector видно, что это делается с помощью атрибута [Conditional ("DEBUG")]
:
public sealed class Debug
{
private Debug();
[Conditional("DEBUG")]
public static void Assert(bool condition);
// etc...
}
Если вам нужна другая подпись, кроме void func (..) без параметров out, что было бы не так с
MyDebugObject Foo(out int justForGrins)
{
justForGrins = <safe value for release builds>;
MyDebugObject result = <safe value for release builds>;
#if DEBUG
.. run code you need for your debugging...
#endif
return result;
}
Он более подробный и менее элегантный, чем ConditionalAttribute, но он позволит вам более гибкую подпись.