Мы пытаемся решить, как решить эту проблему с InvalidCastException.
"ExceptionType": "System.InvalidCastException",
"StackTrace": " at ...Objects.Patient.Equals(Object obj) in
at System.Collections.Generic.ObjectEqualityComparer`1.Equals(T x, T y)\r\n at System.Collections.Generic.List`1.Contains(T item)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference
Фактически, мы нашли похожий пост из прошлого с этим кодом, который также генерирует то же исключение. И чтобы воспроизвести это, мы вставили внутрь простой WinForm:
private void buttonJsonSerializer_Click(object sender, EventArgs e)
{
var fixture = new Fixture
{
Name = "Fixture Name",
participant = new Participant { Name = "Participant Name"}
};
fixture.participant = new Participant();
var writer = new StringWriter(new StringBuilder());
var serializer = new JsonSerializer();
serializer.Converters.Add(new StringEnumConverter());
serializer.Serialize(writer, fixture);
string output = writer.ToString();
}
public class Fixture
{
public string Name { get; set; }
public Participant participant { get; set; }
public override bool Equals(object obj)
{
var fixture = (Fixture)obj; // *** THROWS CAST EXCEPTION ***
return fixture.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class Participant
{
public string Name { get; set; }
public override bool Equals(object obj)
{
var participant = (Participant)obj;
return participant.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
Один из возникших вопросов был: имеет ли это какое-либо отношение к библиотеке Newtonsoft?
Кроме того, использование var fixture = obj as Fixture - это не то, что мы собираемся делать в этом случае, поскольку он просто вернет null.





Вы не можете просто предположить, что аргумент Fixture::Equals всегда будет Fixture:
public override bool Equals(object obj)
{
if (obj is Fixture fixture)
{
return fixture.Name == Name;
}
return false;
}
И вам нужно сделать то же самое для Participant::Equals:
public override bool Equals(object obj)
{
if (obj is Participant participant)
{
return participant.Name == Name;
}
return false;
}
One of questions that came up was: does it have anything to do with the
Newtonsoftlibrary ?
Оно делает:
at UserQuery.Fixture.Equals(Object obj) at System.Collections.Generic.ObjectEqualityComparer
1.Equals(T x, T y)1.Contains(T item) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference(JsonWriter writer, Object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType) at Newtonsoft.Json.JsonSerializer.Serialize(TextWriter textWriter, Object value) at UserQuery.Main() at LINQPad.ExecutionModel.ClrQueryRunner.Run() at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner) at LINQPad.ExecutionModel.Server.StartQuery(QueryRunner runner) at LINQPad.ExecutionModel.Server.<>c__DisplayClass152_0.b__0() at LINQPad.ExecutionModel.Server.SingleThreadExecuter.Work() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
at System.Collections.Generic.List
JsonSerializerInternalWriter::CheckForCircularReference обращается к Equals для справки.
На самом деле это связано с проверкой циклических ссылок. Для подтверждения см. При проверке циклических ссылок следует использовать равенство ссылок на объект # 401, где Джеймс Ньютон-Кинг подтверждает, что проверка циклических ссылок через object.Equals() является предполагаемым поведением: Я предпочитаю текущее поведение, которое позволяет разработчикам настраивать логику, переопределяя Equals.
Просто исправьте свою реализацию Equals. Он должен проверить, является ли obj пациентом, а если нет - должен вернуть false. Как ваша реализация неверна.