C# 获取不同的列表值

C# 获取不同的列表值,c#,asp.net,.net,asp.net-mvc,C#,Asp.net,.net,Asp.net Mvc,我有一个C#应用程序,我想从列表中获取项目对象,另一个包含不同对象的列表 我试过这个 List<Project> model = notre_admin.Get_List_Project_By_Expert(u.Id_user); if (model != null) model = model.Distinct().ToList(); List model=notre\u admin.由\u专家(u.Id\u用户)获取\u List\u项目\u; 如果(model!=null

我有一个C#应用程序,我想从
列表中获取项目对象,另一个包含不同对象的列表

我试过这个

 List<Project> model = notre_admin.Get_List_Project_By_Expert(u.Id_user);
 if (model != null) model = model.Distinct().ToList();
List model=notre\u admin.由\u专家(u.Id\u用户)获取\u List\u项目\u;
如果(model!=null)model=model.Distinct().ToList();
列表模型仍然包含4个相同的对象
Project


这是什么原因?如何修复它?

对象的引用不相等。如果您希望能够对整个对象本身而不仅仅是属性执行此操作,则必须实现IEqualityComparer或IEquatable。

如何定义相同?您应该使用此定义覆盖
Project
中的
Equals
(如果您覆盖
Equals
也覆盖
GetHashCode
)。例如:

public class Project
{
    public int ProjectID { get; set; }

    public override bool Equals(object obj)
    {
        var p2 = obj as Project;
        if (p2 == null) return false;
        return this.ProjectID == m2.ProjectID;
    }

    public override int GetHashCode()
    {
        return ProjectID;
    }
}
if (model != null) model = model.DistinctBy(x => x.Id).ToList();
public static IEnumerable<TItem>
    DistinctBy<TItem, TValue>(this IEnumerable<TItem> items,
    Func<TItem, TValue> selector)
{
    var uniques = new HashSet<TValue>();
    foreach(var item in items)
    {
        if(uniques.Add(selector(item))) yield return item;
    }
}
否则您只是在检查。

您需要在此处定义“相同”。我猜你的意思是“有相同的内容”,但是不是类的默认定义:默认定义是“是相同的实例”

如果希望“相同”表示“具有相同的内容”,则有两个选项:

  • 编写一个自定义比较器(
    IEqualityComparer
    ),并将其作为参数提供给
    Distinct
  • Project
还有一些自定义方法,如
DistinctBy
,可以在许多地方使用,如果标识可以由单个属性确定(
Id
,通常),则该方法很有用,但不在BCL中。但例如:

public class Project
{
    public int ProjectID { get; set; }

    public override bool Equals(object obj)
    {
        var p2 = obj as Project;
        if (p2 == null) return false;
        return this.ProjectID == m2.ProjectID;
    }

    public override int GetHashCode()
    {
        return ProjectID;
    }
}
if (model != null) model = model.DistinctBy(x => x.Id).ToList();
public static IEnumerable<TItem>
    DistinctBy<TItem, TValue>(this IEnumerable<TItem> items,
    Func<TItem, TValue> selector)
{
    var uniques = new HashSet<TValue>();
    foreach(var item in items)
    {
        if(uniques.Add(selector(item))) yield return item;
    }
}
例如:

public class Project
{
    public int ProjectID { get; set; }

    public override bool Equals(object obj)
    {
        var p2 = obj as Project;
        if (p2 == null) return false;
        return this.ProjectID == m2.ProjectID;
    }

    public override int GetHashCode()
    {
        return ProjectID;
    }
}
if (model != null) model = model.DistinctBy(x => x.Id).ToList();
public static IEnumerable<TItem>
    DistinctBy<TItem, TValue>(this IEnumerable<TItem> items,
    Func<TItem, TValue> selector)
{
    var uniques = new HashSet<TValue>();
    foreach(var item in items)
    {
        if(uniques.Add(selector(item))) yield return item;
    }
}
公共静态IEnumerable
区别于(这是一个数不清的项目,
Func选择器)
{
var uniques=new HashSet();
foreach(项目中的var项目)
{
如果(唯一添加(选择器(项目)))生成退货项目;
}
}
或者你可以这样写

var list1 = model.DistinctBy(x=> x.Id_user);

检查此示例:您需要使用Comparator或override
Equals()

类程序
{
静态void Main(字符串[]参数)
{
列表项=新列表();
项目。添加(新项目(“A”);
项目。添加(新项目(“A”);
项目。添加(新项目(“B”);
增加(新项目(“C”);
items=items.Distinct().ToList();
}
}
公共类项目
{
字符串名称{get;set;}
公共项(字符串名称)
{
名称=名称;
}
公共覆盖布尔等于(对象对象对象)
{
返回Name.Equals((对象作为项).Name);
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
}
下面是一个基本相同的问题,它会有所帮助

说明:

Distinct()方法检查引用类型的引用相等性。这意味着它正在寻找字面上相同的复制对象,而不是包含相同值的不同对象


@Rex M.

的积分使用以下方法之一并不简单:)? 您只需按某个键对域对象进行分组,然后选择FirstOrDefault,如下所示

更有趣的选择是创建一些比较器适配器,该适配器将带您访问域对象,并创建比较器可以直接使用/使用的其他对象。基于比较器,您可以创建自定义linq扩展,如下面的示例所示。希望有帮助:)

List passData=(List)TempData[“passData\u Select\u BankName\u List”];
passData=passData?.DistinctBy(b=>b.BankNm).ToList();

它将起作用……

在列表中是不同的,实际上在对象上起作用??在此上下文中定义“相同”。@Henkholtman您能解释更多吗?您需要提供一个相等比较程序。请参阅Distinct()的重载列表。我认为@Henk的意思是“相等/散列应该适合您类型的相等定义,它可能仅限于一个属性,例如
ProjectId
”@MarcGravel:我不知道OP的
项目
类,所以我假设了一些db相关的东西,它有一个标识符,比如
…Id
。为什么我要在OP澄清他对“相同”的定义之前把事情复杂化?正如@MarcGravel所说,对于可变对象,不应该覆盖相等。ProjectID在逻辑上可能是不可变的,这使得这个示例可以接受。但是如果添加一个Name属性,它将以眼泪告终。@Henk的确,跨越多个时间快照的易变性和字典(etc)是一个痛苦的处方。但是,即使名称发生了更改,也可能希望通过ID查找项目(在列表或字典中)。那么,为什么所有属性都必须相同才能标识对象呢?这对我来说毫无意义,但这是不对的;
Distinct()
方法(没有自定义相等比较器)只应用该类型自己的相等定义。它是决定相等含义的类型,而不是
Distinct()我刚刚找到了他使用自定义比较器的答案,我想这正是他想要的;第二种方法不是标准方法。
List<ViewClReceive> passData = (List<ViewClReceive>)TempData["passData_Select_BankName_List"];
    passData = passData?.DistinctBy(b=>b.BankNm).ToList();