10

List<T>私はアカウント オブジェクトのクラスを作成し、それらのアカウント オブジェクトの static を保持します。私のプログラムは、リスト内の各アカウントをループし、アカウントでいくつかの作業を実行し、リストの最後に到達すると一番上にリセットされます。

私の問題は、プログラムが作業を終了した後、更新された情報を追加して、アカウントをリストに再挿入できるようにする必要があることです。IndexOf() 関数を使用して静的リスト内のオブジェクトをチェックするか、データを追加したために失敗しますか? 2 つのオブジェクトが同じかどうかを確認するために比較するフィールドがわかりません。

注: リスト内での重複は許可されていないため、間違った項目を更新するリスクはありません

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);
   }
}
4

5 に答える 5

13

別のオプションは、List.FindIndexを使用して、述語を渡すことです。あれは:

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

そうすれば、任意のフィールドまたはフィールド数で検索できます。これは、オーバーロードされたメソッドAccountを追加するためのソース コードにアクセスできない場合に特に便利です。Equals

于 2013-08-01T21:57:09.567 に答える
11

受け入れられた回答がカバーしていないことの1つは、オーバーライドEquals(object)GetHashCode()IEquatable<T>正しく機能することになっていることです。完全な実装は次のとおりです(keyboardPの回答に基づく)

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);
    }
}
于 2013-08-01T21:43:47.087 に答える
10

オブジェクトは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);
    }
}
于 2013-08-01T20:31:15.177 に答える
4

クラスが を適切に実装している場合IEquatable<T>、はメソッドをIndexOf()使用Equals()して等しいかどうかをテストします。

それ以外の場合は、IndexOf()参照の等価性が使用されます。

于 2013-08-01T20:38:51.500 に答える