在C#中创建一个独特的自定义类型列表

时间:2012-03-07 12:38:01

标签: c# .net linq

我收到了一个实体框架类型的列表,并希望只返回List中的不同值。我正在使用以下方法,但它并没有统一列表。有什么建议吗?

Param:List<Flag> flags

List<Flag> distinctFlags = flags.Distinct().ToList();

Flag的值如下:ID,Flag,FlagValue。我可以在这个例子中使用linq吗?

感谢。

2 个答案:

答案 0 :(得分:16)

假设Flag是您的某个实体模型,您可以使用partial class并覆盖EqualsGetHashCode。这也假设您在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();

答案 1 :(得分:1)

可能flags是引用类型列表,而distinct不能按预期工作! 这是因为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方法确切地知道如何比较equals flag istance。

<强>更新

根据您的评论,如果您想按照我的建议,您应该编写比较基数如下:

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;
        }
    }

当然,每个属性都必须是值类型。

看看这里澄清自己: