List .IndexOf()如何执行自定义对象的比较?

我写了一类帐户对象并保存这些帐户对象的静态List 。 我的程序循环遍历列表中的每个帐户,对帐户执行一些操作,然后在到达列表末尾时在顶部重置。

我的问题是,在我的程序完成后,我需要能够将帐户重新插入列表中,并添加了一些更新的信息。 我是否可以按照下面的说明执行此操作,使用IndexOf()函数检查静态列表中的对象,还是因为我向其添加数据而失败? 我不明白它比较哪些字段以查看两个对象是否相同。

注意:列表中不允许重复,因此不存在更新错误项目的风险

 public class Account { public string name; public string password; public string newInfo; } public static class Resources { private static List AccountList = new List(); private static int currentAccountIndex = 0; public static Account GetNextAccount() { if (currentAccountIndex > AccountList.Count) currentAccountIndex = 0; return AccountList[currentAccountIndex++]; } public static void UpdateAccount(Account account) { int index; if ((index = AccountList.IndexOf(account)) >= 0) AccountList[index] = account; } } public class Program { public void PerformWork() { Account account = Resources.GetNextAccount(); // Do some work account.newInfo = "foo"; Resources.UpdateAccount(account); } } 

您的对象应该实现IEquatable接口并覆盖Equals方法。

 public class Account : IEquatable { public string name; public string password; public string newInfo; public bool Equals(Account other) { //Choose what you want to consider as "equal" between Account objects //for example, assuming newInfo is what you want to consider a match //(regardless of case) if (other == null) return false; return String.Equals(this.newInfo, other.newInfo, StringComparison.OrdinalIgnoreCase); } } 

另一种选择是使用List.FindIndex ,并传递谓词。 那是:

 if ((index = AccountList.FindIndex(a => a.name == account.name)) >= 0) AccountList[index] = account; 

这样,您可以搜索任意字段或字段数。 如果您无权访问Account的源代码以添加重载的Equals方法,则此function尤其有用。

接受的答案没有涉及的一件事是你应该重写Equals(object)GetHashCode()以使IEquatable正常工作。 这是完整的实现(基于keyboardP的答案 )

 public class Account : IEquatable { public string name; public string password; public string newInfo; private readonly StringComparer comparer = StringComparer.OrdinalIgnoreCase; public override bool Equals(object other) { //This casts the object to null if it is not a Account and calls the other Equals implementation. return this.Equals(other as Account); } public override int GetHashCode() { return comparer.GetHashCode(this.newInfo) } public bool Equals(Account other) { //Choose what you want to consider as "equal" between Account objects //for example, assuming newInfo is what you want to consider a match //(regardless of case) if (other == null) return false; return comparer.Equals(this.newInfo, other.newInfo); } } 

如果你的类正确地实现了IEquatable ,那么IndexOf()将使用你的Equals()方法来测试相等性。

否则, IndexOf()将使用引用相等性。