Mam pewien kod, który odwzorowuje silnie typowane obiekty biznesowe na typy anonimowe, które następnie są serializowane do JSON i odsłonięte za pośrednictwem interfejsu API.Dlaczego Object.Equals() zwraca false dla identycznych typów anonimowych, gdy są tworzone z różnych zestawów?
Po restrukturyzacji mojego rozwiązania na osobne projekty, niektóre z moich testów zaczęły zawieść. Zrobiłem trochę kopania i okazuje się, że Object.Equals
zachowuje się inaczej na anonimowych typach, które są zwracane przez kod z innego zespołu - i nie jestem pewien, dlaczego lub co mogę zrobić, aby obejść to.
Istnieje pełny kod repro w https://github.com/dylanbeattie/AnonymousTypeEquality, ale bit, który faktycznie łamie się, znajduje się poniżej. Ten kod jest w projekcie badania:
[TestFixture]
public class Tests {
[Test]
public void BothInline() {
var a = new { name = "test", value = 123 };
var b = new { name = "test", value = 123 };
Assert.That(Object.Equals(a,b)); // passes
}
[Test]
public void FromLocalMethod() {
var a = new { name = "test", value = 123 };
var b = MakeObject("test", 123);
Assert.That(Object.Equals(a, b)); // passes
}
[Test]
public void FromOtherNamespace() {
var a = new { name = "test", value = 123 };
var b = OtherNamespaceClass.MakeObject("test", 123);
Assert.That(Object.Equals(a, b)); // passes
}
[Test]
public void FromOtherClass() {
var a = new { name = "test", value = 123 };
var b = OtherClass.MakeObject("test", 123);
/* This is the test that fails, and I cannot work out why */
Assert.That(Object.Equals(a, b));
}
private object MakeObject(string name, int value) {
return new { name, value };
}
}
a następnie istnieje odrębna biblioteka klasy w roztworze zawierającym tylko to:
namespace OtherClasses {
public static class OtherClass {
public static object MakeObject(string name, int value) {
return new { name, value };
}
}
}
Według MSDN „dwie instancje samego typu anonimowego są równe, jeśli wszystkie ich właściwości są równe. " (mój nacisk) - więc co kontroluje, czy dwie instancje mają ten sam anonimowy typ dla celów porównawczych? Moje dwa wystąpienia mają jednakowe kody skrótu, a oba wydają się być <>f__AnonymousType0`2[System.String,System.Int32]
- ale domyślam się, że równość dla typów anonimowych musi uwzględniać w pełni kwalifikowaną nazwę typu, a zatem przeniesienie kodu do innego zespołu może spowodować błędy. Ktoś dostał ostateczne źródło/link dokładnie o tym, jak jest to realizowane?
Nie mam problemu z ukąszeniem raz na jakiś czas ... dobrze jest wiedzieć, co dokładnie zrobiłeś, aby sprowokować ukąszenie. :) –
@DylanBeattie Rzuciłeś anonimowy typ na 'object'. Nigdy tego nie rób. Zachowaj typ ogólny (tak jak robi LINQ) lub upewnij się, że jest lokalny z poprawnym typem. Wszystko inne to prohibidado. – Luaan