私は、元のオブジェクトと複製されたオブジェクトで組み込みのシリアライザーの 1 つを使用する単体テストを作成し、シリアル化された表現が等しいかどうかをチェックするのが好きです (バイナリ フォーマッタの場合は、バイト配列を比較するだけです)。これは、オブジェクトがまだシリアライズ可能な場合にうまく機能し、パフォーマンス上の理由からカスタムのディープ クローンに変更するだけです。
さらに、このようなものを使用して、すべての Clone 実装にデバッグ モード チェックを追加するのが好きです。
[Conditional("DEBUG")]
public static void DebugAssertValueEquality<T>(T current, T other, bool expected,
params string[] ignoredFields) {
if (null == current)
{ throw new ArgumentNullException("current"); }
if (null == ignoredFields)
{ ignoredFields = new string[] { }; }
FieldInfo lastField = null;
bool test;
if (object.ReferenceEquals(other, null))
{ Debug.Assert(false == expected, "The other object was null"); return; }
test = true;
foreach (FieldInfo fi in current.GetType().GetFields(BindingFlags.Instance)) {
if (test = false) { break; }
if (0 <= Array.IndexOf<string>(ignoredFields, fi.Name))
{ continue; }
lastField = fi;
object leftValue = fi.GetValue(current);
object rightValue = fi.GetValue(other);
if (object.ReferenceEquals(null, leftValue)) {
if (!object.ReferenceEquals(null, rightValue))
{ test = false; }
}
else if (object.ReferenceEquals(null, rightValue))
{ test = false; }
else {
if (!leftValue.Equals(rightValue))
{ test = false; }
}
}
Debug.Assert(test == expected, string.Format("field: {0}", lastField));
}
このメソッドは、ネストされたメンバーでの Equals の正確な実装に依存していますが、私の場合、クローン可能なものはすべて同等です