我有List<Moves> listOfMoves
ListOfMoves.Add(new Moves()
{
int position1= number1,
int position2= number2,
});
现在我想检查ListOfMoves
是否包含例如Move(2,3)
,但也要检查它是否包含Move(3,2)
。我尝试了if(ListOfMoves.Contains(new Move(2,3)))
,但它不能正常工作。
方法List<T>.Contains(T item)
在内部使用方法Object.Equals
来检查对象是否相等。因此,如果要将方法List<T>.Contains(T item)
与类型T
一起使用以检查指定的item
是否包含在List<T>
中,则需要覆盖类型T
中的方法Object.Equals
。
当您覆盖Object.Equals
时,您也应该覆盖Object.GetHashCode
。这里有一个很好的解释"当Equals方法被重写时,为什么重写GetHashCode很重要?"。
以下是如何在Move
类中重写Object.Equals
以满足您的需求:
class Move
{
public Move(int p1, int p2)
{
position1 = p1;
position2 = p2;
}
public int position1 { get; }
public int position2 { get; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (ReferenceEquals(this, obj))
return true;
Move other = obj as Move;
if (other == null)
return false;
// Here we specify how to compare two Moves. Here we implement your
// requirement that two moves are considered equal regardless of the
// order of the properties.
return (position1 == other.position1 && position2 == other.position2) ||
(position1 == other.position2 && position2 == other.position1);
}
public override int GetHashCode()
{
// When implementing GetHashCode we have to follow the next rules:
// 1. If two objects are equal then their hash codes must be equal too.
// 2. Hash code must not change during the lifetime of the object.
// Therefore Move must be immutable. (Thanks to Enigmativity's usefull tip).
return position1 + position2;
}
}
当您覆盖Object.Equals
时,您将能够使用条件ListOfMoves.Contains(new Move(2, 3))
来检查移动Move(2, 3)
或Move(3, 2)
是否包含在ListOfMoves
中。
以下是演示Object.Equals
覆盖的完整示例。
为此,您可以使用LINQ的Any函数。如果你想要位置[(2,3(或(3,2(]的两个组合,你需要两次通过两次检查
ListOfMoves.Any(x =>
(x.position1 == 2 && x.position2 == 3)
|| (x.position1 == 3 && x.position2 == 2) )
Any返回一个bool,因此您可以将这行代码包装在if语句中,或者存储多次使用的结果
潜在改进
如果你要做很多这样的检查(并且你至少使用c版本7(,你可以考虑一些小的重构,并使用内置的元组类型:https://learn.microsoft.com/en-us/dotnet/csharp/tuples
移动将成为
public class Moves
{
public (int position1, int position2) positions { get; set; }
}
任何呼叫都将成为
ListOfMoves.Any(x => x.positions == (2,3) || x.positions == (3,2))
否则,在代码中,您仍然可以访问每个位置的基本值:
ListOfMoves[0].positions.position1
显然,这取决于代码中的其他内容,所以完全取决于您!
显然它不起作用,因为您无法比较实体本身,而必须使用System.Linq
与以下属性值进行比较
ListOfMoves.Where(x => x.position1 == 2 && x.position1 == 3)
注意:您发布的代码根本不应该在中编译
你说如果Move(3,2(或(2,3(在List中,我需要得到true
然后使用Any()
,使用类似的相同谓词
if(ListOfMoves.Any(x => x.position1 == 2 && x.position1 == 3))
{
// done something here
}