我的主要问题描述如下:
我有两个BankAccount对象列表.A BankAccount具有诸如BankCode并且AccountNumber唯一标识帐户的属性.因此,无论该列表可能包含同一个银行帐户,但他们可能有他们Source,Amount或AccountTypes有所不同.
这里的目的是合并这两个列表:
我试过实现一篇SO帖子中提到的解决方案.我去尝试在.NET代码填充网站上编写代码.但是在尝试执行行号后,我无法获得输出.93我评论过.
class BankAccount
{
public string BankCode{get;set;}
public string AccountNumber{get;set;}
public string AccountType{get;set;}
public string Amount{get;set;}
public string Source{get;set;}
public override bool Equals(object obj)
{
var acc = obj as BankAccount;
return Equals(acc);
}
public override int GetHashCode()
{
return this.GetHashCode();
}
public bool Equals(BankAccount acc2)
{
if(acc2 == null) return false;
if(string.IsNullOrEmpty(acc2.BankCode)) return false;
if(string.IsNullOrEmpty(acc2.AccountNumber)) return false;
return this.BankCode.Equals(acc2.BankCode) && this.AccountNumber.Equals(acc2.AccountNumber);
}
}
//List<BankAccount> lst3 = lst.Union(lst1).ToList(); // line 93
Run Code Online (Sandbox Code Playgroud)
完整代码可以在这里查看.
PS:我不确定这是否可能是键盘网站的问题.
更新 - 2011年2月14日星期一 - 格林威治标准时间4:50:24(am)/ 04:50:24
Thanx更新.但有些事情仍然存在问题.在输出中,列表3的第一项应具有AccountType=P和Source=lst2.第二个要求未得到满足.我的数字Union()只是我需要的一部分.我需要做什么才能满足第二个要求.
由drachenstern 编辑:我不确定这个标题是否更好,但它确实比之前的标题更具信息性的实际问题:\
解决方案1:
此解决方案未达到您(新)规定的2个要求,但旨在解决您尝试使用LINQ Union()解决问题的问题.
您有一个递归调用,导致此行上的堆栈溢出异常(23):
public override int GetHashCode()
{
return this.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
我建议将其更改为以下内容:
public override int GetHashCode()
{
return (BankCode + AccountNumber).GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
编辑:
确保成员BankCount和AccountNumber永远不会为null或抛出异常.我建议你查找覆盖GetHashCode()方法的标准做法.
Resharper的自动生成的GetHashCode覆盖:(如果交换了BankCode和AccountNumber,则397值确保数字不会发生冲突.未选中意味着数字不会出现溢出问题*397)
public override int GetHashCode()
{
unchecked
{
return ((BankCode != null ? BankCode.GetHashCode() : 0)*397) ^ (AccountNumber != null ? AccountNumber.GetHashCode() : 0);
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案2:
该解决方案旨在实现您的2个要求,而无需使用LINQ Union().
如果您想要合并列表,使用第二个列表作为首选项,那么也许尝试这样:
var mergedList = new List<BankAccount>();
// add items from lst or any duplicates from lst1
foreach (var bankAccount in lst)
{
var account = bankAccount;
var dupe = lst1.FirstOrDefault(item => item.Equals(account));
mergedList.Add(dupe ?? bankAccount);
}
// add any items in lst1 that are not duplicates
foreach (var bankAccount in lst1.Where(item=>!mergedList.Contains(item)))
{
mergedList.Add(bankAccount);
}
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找代码最小化:
// add items from lst or any duplicates from lst1
var temp = lst.Select(item => lst1.FirstOrDefault(item1 => item1.Equals(item)) ?? item);
// add any items in lst1 that are not duplicates
var result = temp.Union(lst1.Where(item => !temp.Contains(item)));
Run Code Online (Sandbox Code Playgroud)