我编写了一类帐户对象并保留了这些帐户对象的静态List<T>
。我的程序循环遍历列表中的每个帐户,对帐户执行一些操作,然后在到达列表末尾时在顶部重置。
我的问题是,在我的程序完成后,我需要能够将帐户重新插入列表中,并添加了一些更新的信息。我是否可以按照下面的说明执行此操作,使用IndexOf()函数检查静态列表中的对象,还是因为我向其添加数据而失败?我不明白它比较哪些字段以查看两个对象是否相同。
注意:列表中不允许重复,因此不存在更新错误项目的风险
public class Account
{
public string name;
public string password;
public string newInfo;
}
public static class Resources
{
private static List<Account> AccountList = new List<Account>();
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);
}
}
答案 0 :(得分:9)
另一种选择是使用List.FindIndex,并传递一个谓词。那就是:
if ((index = AccountList.FindIndex(a => a.name == account.name)) >= 0)
AccountList[index] = account;
通过这种方式,您可以搜索任意字段或字段数。如果您无权访问Account
的源代码以添加重载的Equals
方法,则此功能特别有用。
答案 1 :(得分:8)
您的对象应实现IEquatable接口并覆盖Equals
方法。
public class Account : IEquatable<Account>
{
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);
}
}
答案 2 :(得分:4)
如果您的班级正确实施IEquatable<T>
,那么IndexOf()
将使用您的Equals()
方法来测试是否相等。
否则,IndexOf()
将使用引用相等。
答案 3 :(得分:4)
接受的答案没有涉及的一件事是你应该覆盖Equals(object)
和GetHashCode()
以使IEquatable<T>
正常工作。这是完整的实现(基于keyboardP's answer)
public class Account : IEquatable<Account>
{
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);
}
}
答案 4 :(得分:0)
您可以为类使用自定义谓词,例如:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
然后您可以按以下方式使用它:
public class Account
{
public string name;
public string password;
public string newInfo;
public class IndexOfName
{
private string _match = "";
public IndexOfName()
{
}
public Predicate<Account> Match(string match)
{
this._match = match;
return IsMatch;
}
private bool IsMatch(Account matchTo)
{
if (matchTo == null)
{
return false;
}
return matchTo.Equals(this._match);
}
}
}
您甚至可以更改IndeOfName类,以使用标志在要查找的信息类型之间切换。例如:名称或newInfo。