C# 获取不同的列表值
我有一个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
列表中获取项目对象,另一个包含不同对象的列表
我试过这个
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或overrideEquals()
类程序
{
静态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();