Skip to content

Further issues in DeepClone of self-referenced classes containing read only fields / properties #15

@maxbruecken

Description

@maxbruecken

In addition to issue #14 there are two further issues while cloning objects using iterative approach.

  • if the class hierarchy contains a read only field / property of value type (e.g. decimal)
  • if the class hierarchy contains multiple read only fields / properties

Attached tests should show both issues. I have created a pull request with fixes for both issues.

[Test]
public void SelfReferenced_WithInitOnlyValueTypeField_Test()
{
	SelfReferencedWithInitOnlyValueTypeField original = new SelfReferencedWithInitOnlyValueTypeField
	{
		WithReadOnlyValueTypeField = new ClassWithReadOnlyValueField()
	};

	SelfReferencedWithInitOnlyValueTypeField clone = original.DeepClone();
	
	Assert.That(clone, Is.Not.SameAs(original));
	Assert.That(clone.WithReadOnlyValueTypeField, Is.Not.SameAs(original.WithReadOnlyValueTypeField));
	Assert.That(clone.WithReadOnlyValueTypeField.ReadOnlyValue, Is.EqualTo(original.WithReadOnlyValueTypeField.ReadOnlyValue));
}

private class SelfReferencedWithInitOnlyValueTypeField
{
	public SelfReferencedWithInitOnlyValueTypeField? Predecessor { get; set; }
	
	public ClassWithReadOnlyValueField WithReadOnlyValueTypeField { get; set; }
}

private class ClassWithReadOnlyValueField
{
	private readonly decimal readOnlyField = 1m;
	public decimal ReadOnlyValue => readOnlyField;
}

[Test]
public void SelfReferenced_WithMultipleReadOnlyProperties_Test()
{
	SelfReferencedWithMultipleReadOnlyProperties original = new SelfReferencedWithMultipleReadOnlyProperties
	{
		WithMultipleReadOnlyProperties = new ClassWithMultipleReadOnlyProperties()
	};

	SelfReferencedWithMultipleReadOnlyProperties clone = original.DeepClone();
	
	Assert.That(clone, Is.Not.SameAs(original));
	Assert.That(clone.WithMultipleReadOnlyProperties, Is.Not.SameAs(original.WithMultipleReadOnlyProperties));
	Assert.That(clone.WithMultipleReadOnlyProperties.Name, Is.EqualTo(original.WithMultipleReadOnlyProperties.Name));
	Assert.That(clone.WithMultipleReadOnlyProperties.Id, Is.EqualTo(original.WithMultipleReadOnlyProperties.Id));
}

private class SelfReferencedWithMultipleReadOnlyProperties
{
	public SelfReferencedWithMultipleReadOnlyProperties? Predecessor { get; set; }

	public ClassWithMultipleReadOnlyProperties WithMultipleReadOnlyProperties { get; set; }
}

private class ClassWithMultipleReadOnlyProperties
{
	public int Id { get; } = 1;
	public string Name { get; } = "Test";
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions