简体   繁体   English

C#中不同的对象列表

[英]Distinct List of object in C#

I have to distinct list of object but NOT only by ID because sometimes two different objects have same ID. 我必须区分对象列表,而不仅仅是ID,因为有时两个不同的对象具有相同的ID。 I have class: 我有课:

public class MessageDTO
{

    public MessageDTO(MessageDTO a)
    {
        this.MsgID = a.MsgID;
        this.Subject = a.Subject;
        this.MessageText = a.MessageText;
        this.ViewedDate = a.ViewedDate;
        this.CreatedDate = a.CreatedDate;
    }

    public int? MsgID { get; set; }
    public string Subject { get; set; }
    public string MessageText { get; set; }
    public System.DateTime? ViewedDate { get; set; }
    public System.DateTime? CreatedDate { get; set; }
}

How I can distinct list of: 如何区分以下内容:

List<MessageDTO> example;

Thanks 谢谢

Use LINQ. 使用LINQ。

public class MessageDTOEqualityComparer : EqualityComparer<MessageDTO>
{
    public bool Equals(MessageDTO a, MessageDTO b)
    {
        // your logic, which checks each messages properties for whatever
        // grounds you need to deem them "equal." In your case, it sounds like
        // this will just be a matter of iterating through each property with an
        // if-not-equal-return-false block, then returning true at the end
    }

    public int GetHashCode(MessageDTO message)
    {
        // your logic, I'd probably just return the message ID if you can,
        // assuming that doesn't overlap too much and that it does
        // have to be equal on the two
    }
}

Then 然后

return nonDistinct.Distinct(new MessageDTOEqualityComparer());

You can also avoid the need for an extra class by overriding object.Equals(object) and object.GetHashCode() and calling the empty overload of nonDistinct.Distinct() . 您也可以通过重写避免一个额外的类需要object.Equals(object)object.GetHashCode()和调用的空超载nonDistinct.Distinct() Make sure you recognize the implications of this decision, though: for instance, those will then become the equality-testing functions in all non-explicit scopes of their use. 但是,请确保您了解此决定的含义:例如,这些将在其使用的所有非显式范围内成为相等性测试功能。 This might be perfect and exactly what you need, or it could lead to some unexpected consequences. 这可能是完美的,正是您所需要的,否则可能会导致一些意外的后果。 Just make sure you know what you're getting into. 只要确保您知道自己正在进入什么。

I you want to use other properties, you should implement IEqualityComparer interface. 我要使用其他属性,则应实现IEqualityComparer接口。 More on: msdn 更多信息: msdn

class MsgComparer : IEqualityComparer<MessageDTO>
{
    public bool Equals(MessageDTO x, MessageDTO Oy)
    {
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(MessageDTO m)
    {
           //it must br overwritten also
    }

}

Then: 然后:

example.Distinct(new MsgComparer());

You could also overwrite Equals in MessageDTO class: 您还可以覆盖 MessageDTO类中的Equals

class MessageDTO 
{
    // rest of members
    public override bool Equals(object obj) 
    {
        // your stuff. See: http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx
    }
    public override int GetHashCode()
    {
    }
}

Then it's enough: 然后就足够了:

example.Distinct();

You could use the extension method DistinctBy from the MoreLinq library: 您可以使用MoreLinq库中的扩展方法DistinctBy:

string[] source = { "first", "second", "third", "fourth", "fifth" };
var distinct = source.DistinctBy(word => word.Length);

See here : 这里

I recommend you using solution of @Matthew Haugen 我建议您使用@Matthew Haugen的解决方案

In case you don't want to create a new class for that, there is a way to use LINQ by grouping you list by distinct field(s) then select the first item on this group. 如果您不想为此创建新类,则可以通过使用按不同字段对列表进行分组,然后选择该组中的第一项来使用LINQ。 For example: 例如:

example.(e => new { e.MsgID, e.Subject }).Select(grp => grp.FirstOrDefault());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM