How does List<T>.IndexOf() perform comparisons on custom objects?
Another option is to use List.FindIndex, and pass a predicate. That is:
if ((index = AccountList.FindIndex(a => a.name == account.name)) >= 0)
AccountList[index] = account;
That way you can search on any arbitrary field or number of fields. This is especially useful if you don't have access to the source code for Account
to add an overloaded Equals
method.
Your object should implement the IEquatable interface and override the Equals
method.
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);
}
}
One thing the accepted answer did not cover is you are supposed to override Equals(object)
and GetHashCode()
for IEquatable<T>
to work correctly. Here is the full implementation (based off of 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);
}
}