Ниже, используя отражение, кажется мне лучшим вариантом с учетом общедоступных свойств, так как с этим вам не нужно беспокоиться о добавлении / удалении свойств (хотя это не так распространенный сценарий). Это, как мне показалось, лучше работает. (По сравнению с секундомером).
public int getHashCode()
{
PropertyInfo[] theProperties = this.GetType().GetProperties();
int hash = 31;
foreach (PropertyInfo info in theProperties)
{
if (info != null)
{
var value = info.GetValue(this,null);
if(value != null)
unchecked
{
hash = 29 * hash ^ value.GetHashCode();
}
}
}
return hash;
}
У меня есть это в некотором модульном тесте здесь в задании:
MyComplexObject dto = new MyComplexObject();
MemoryStream mem = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
try
{
b.Serialize(mem, dto);
}
catch (Exception ex)
{
Assert.Fail(ex.Message);
}
Мог бы помочь Вам..., возможно, другой метод может быть лучше, но эти работы хорошо.
Вот универсальный путь:
public static Stream Serialize(object source)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
formatter.Serialize(stream, source);
return stream;
}
public static T Deserialize<T>(Stream stream)
{
IFormatter formatter = new BinaryFormatter();
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
public static T Clone<T>(object source)
{
return Deserialize<T>(Serialize(source));
}
сериализируйте объект (к памяти или диску), десериализуйте его, используйте отражение для сравнения этих двух, тогда выполняет все модульные тесты на тот объект снова (кроме сериализации, конечно)
, это предполагает, что модульные тесты могут принять объект как цель вместо того, чтобы делать их собственное
В дополнение к тесту выше - который удостоверяется, сериализатор примет Ваш объект, необходимо сделать тест туда и обратно. Десериализуйте результаты назад к новому объекту и удостоверьтесь, что эти два экземпляра эквивалентны.