Создание отдельного списка настраиваемого типа в С#
Я получаю список типов сущностей en entity и хочу возвращать только отдельные значения из списка. Я использую следующий подход, однако это не является уникальным списком. Любые предложения?
Параметр: List<Flag> flags
List<Flag> distinctFlags = flags.Distinct().ToList();
Значения флага следующие: ID, Flag, FlagValue. Могу ли я использовать linq в этом экземпляре?
Спасибо.
Ответы
Ответ 1
Предполагая, что Flag
является одной из ваших моделей сущностей, вы можете использовать partial
class
и переопределить Equals
и GetHashCode
. Это также предполагает, что у вас есть свойство Id
на вашем Flag
class
, которое однозначно идентифицирует его.
//this namespace MUST match the namespace of your entity model.
namespace Your.Entity.Model.Namespace
{
public partial class Flag
{
public override bool Equals(object obj)
{
var item = obj as Flag;
if (item == null)
{
return false;
}
return this.Id.Equals(item.Id);
}
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
}
}
Использование будет выглядеть следующим образом
List<Flag> distinctFlags = allFlags.Distinct().ToList();
Ответ 2
Вероятно, flags
- это список ссылочного типа, а отдельный не работает так, как вы ожидаете!
Это потому, что Distinct() работает не по значению флага в списке, а по его ссылкам на память (все они разные).
Вам нужно написать класс сравнения, который учит отличать, как сравнивать равный флаг. Предположим, что у вас есть этот класс флагов:
public class flag
{
public string Name { get; set; }
public string Code { get; set; }
}
вам следует создать класс сравнения следующим образом:
class FlagComparer : IEqualityComparer<flag>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(flag x, flag y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}
}
и вызов вашего заявления:
List distinctFlags = flags.Distinct(new FlagComparer ()).ToList();
Таким образом, метод Distinct точно знает, как сравнивать equal flag istance.
UPDATE
На основании вашего комментария, если вы хотите следовать моему предложению, вы должны написать базу сравнения следующим образом:
class FlagComparer : IEqualityComparer<flag>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(flag x, flag y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
//Check whether the products' properties are equal.
return x.HostID == y.HostID && x.RuleID == y.RuleID && x.Flag == y.Flag && x.FlagValue == y.FlagValue;
}
}
Конечно, каждое свойство должно быть типом значения.
Взгляните сюда, чтобы уточнить: