Listについて<br>のExistsとContainsの違い
22133 ワード
転載:http://www.cnblogs.com/jicheng1014/archive/2010/02/01/1660967.html
今日は小さなプロジェクトをするとき、リストの中のオブジェクトが存在したかどうかを比較する必要があります.
比較するオブジェクトは新規作成(逆シーケンス化)
Containsを使って比較していると、
問題に気づいた.
以下はテストコードです
テスト結果は次のとおりです.
結論として,新規そっくりのオブジェクトがContainsで返されたfalseは,テストに合格できなかった.
なぜこのような問題が発生したのでしょうか.
答えは簡単です:Containsは記憶されているメモリアドレスが同じかどうかを比較して、値が同じではありません.
テストを変更すると、問題が見つかります.
結果は
明らかに、私が直接Parentからオブジェクトを取得すると、Containsはこのオブジェクトを捕まえます.
では、私が値の比較が必要だとしたら、どうすればいいのでしょうか.
簡単です.predicate委任を定義して、比較方法を指定できます.
(ここではPredicate委任を明示的に宣言する代わりに匿名委任を使用します)
テストに簡単に合格
OK,依頼の比較実行に成功した.
結論
================================
ListのContainsはオブジェクトに対する「メモリ検出」であり、
リストに宣言したオブジェクトと同じ値のオブジェクトがあるかどうかを確認したい場合
Existsメソッドが必要であり、比較方法を指定するためにPredicate委任を実現する必要があります.
================================
今日は小さなプロジェクトをするとき、リストの中のオブジェクトが存在したかどうかを比較する必要があります.
比較するオブジェクトは新規作成(逆シーケンス化)
Containsを使って比較していると、
問題に気づいた.
以下はテストコードです
[TestMethod()]
public void RemoveDiscendantPowerTest() {
Power Parent = new Power
{
Alias = "testRoot",
CanDelete = false,
Description = " ",
id = 100,
PowerName = " ",
Childs = new List<Power>
{
new Power{
Alias = "testBranch1",
CanDelete = true,
Description = " 1",
id = 100100,
PowerName = " 1",
Childs = new List<Power>{
new Power{
Alias = "leaf1",
CanDelete = true,
Description = " 1",
id = 100100100,
PowerName = " 1"
},
new Power{
Alias = "leaf2",
CanDelete = true,
Description = " 2",
id = 100100101,
PowerName = " 2"
}
}
},
new Power{
Alias ="testBranch2",
CanDelete = true,
Description = " 2",
id = 100101,
PowerName = " 2",
Childs = new List<Power>{
new Power{
Alias = "leaf3",
CanDelete = true,
Description = " 3",
id = 100101100,
PowerName = " 3"
},
new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
}
}
}
}
}; // TODO:
Power Discendant = new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
};
// TODO:
Assert.IsTrue(Parent.Childs[1].Childs.Contains(Discendant), " ,Contains ");
}
テスト結果は次のとおりです.
結論として,新規そっくりのオブジェクトがContainsで返されたfalseは,テストに合格できなかった.
なぜこのような問題が発生したのでしょうか.
答えは簡単です:Containsは記憶されているメモリアドレスが同じかどうかを比較して、値が同じではありません.
テストを変更すると、問題が見つかります.
/// <summary>
///RemoveDiscendantPower
///</summary>
[TestMethod()]
public void RemoveDiscendantPowerTest() {
Power Parent = new Power
{
Alias = "testRoot",
CanDelete = false,
Description = " ",
id = 100,
PowerName = " ",
Childs = new List<Power>
{
new Power{
Alias = "testBranch1",
CanDelete = true,
Description = " 1",
id = 100100,
PowerName = " 1",
Childs = new List<Power>{
new Power{
Alias = "leaf1",
CanDelete = true,
Description = " 1",
id = 100100100,
PowerName = " 1"
},
new Power{
Alias = "leaf2",
CanDelete = true,
Description = " 2",
id = 100100101,
PowerName = " 2"
}
}
},
new Power{
Alias ="testBranch2",
CanDelete = true,
Description = " 2",
id = 100101,
PowerName = " 2",
Childs = new List<Power>{
new Power{
Alias = "leaf3",
CanDelete = true,
Description = " 3",
id = 100101100,
PowerName = " 3"
},
new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
}
}
}
}
}; // TODO:
Power Discendant = new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
};
// TODO:
//Assert.IsTrue(Parent.Childs[1].Childs.Contains(Discendant), " ,Contains ");
Power test = Parent.Childs[1].Childs[1];
Assert.IsTrue(Parent.Childs[1].Childs.Contains(test), " , ");
}
結果は
明らかに、私が直接Parentからオブジェクトを取得すると、Containsはこのオブジェクトを捕まえます.
では、私が値の比較が必要だとしたら、どうすればいいのでしょうか.
簡単です.predicate委任を定義して、比較方法を指定できます.
/// <summary>
///RemoveDiscendantPower
///</summary>
[TestMethod()]
public void RemoveDiscendantPowerTest() {
Power Parent = new Power
{
Alias = "testRoot",
CanDelete = false,
Description = " ",
id = 100,
PowerName = " ",
Childs = new List<Power>
{
new Power{
Alias = "testBranch1",
CanDelete = true,
Description = " 1",
id = 100100,
PowerName = " 1",
Childs = new List<Power>{
new Power{
Alias = "leaf1",
CanDelete = true,
Description = " 1",
id = 100100100,
PowerName = " 1"
},
new Power{
Alias = "leaf2",
CanDelete = true,
Description = " 2",
id = 100100101,
PowerName = " 2"
}
}
},
new Power{
Alias ="testBranch2",
CanDelete = true,
Description = " 2",
id = 100101,
PowerName = " 2",
Childs = new List<Power>{
new Power{
Alias = "leaf3",
CanDelete = true,
Description = " 3",
id = 100101100,
PowerName = " 3"
},
new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
}
}
}
}
}; // TODO:
Power Discendant = new Power{
Alias = "leaf4",
CanDelete = true,
Description = " 4",
id = 100101101,
PowerName = " 4"
};
// TODO:
//Assert.IsTrue(Parent.Childs[1].Childs.Contains(Discendant), " ,Contains ");
//Power test = Parent.Childs[1].Childs[1];
//Assert.IsTrue(Parent.Childs[1].Childs.Contains(test), " , ");
Assert.IsTrue(Parent.Childs[1].Childs.Exists(delegate(Power t) {
return t.id == 100101101;
}));
}
(ここではPredicate委任を明示的に宣言する代わりに匿名委任を使用します)
テストに簡単に合格
OK,依頼の比較実行に成功した.
結論
================================
List
リスト
Existsメソッドが必要であり、比較方法を指定するためにPredicate委任を実現する必要があります.
================================