This is a follow up question to my previous one, Make a deep copy of an object inside a ConcurrentDictionary in C#. I want to clone my Patient object so that the object PatientCovariates is the same for the copy.
But when I do that, I also want to regenerate the Random Crn to the same object that was created when the Patient struct was constructed by using _seed.
At the same time, I would like to keep Crn readonly and _seed private and readonly. Is this possible?
using System.Collections.Concurrent;
using System.Text.Json;
namespace ExampleCode;
internal class Program
{
private static void Main(string[] args)
{
Exampel obj = new();
obj.DoStuff();
}
}
internal class Exampel()
{
/// <summary>
/// For the baseline patients (patient ID, patient object), same for all arms and only generated once
/// </summary>
private ConcurrentDictionary<int,
Patient> _baselinePatients = new();
/// <summary>
/// Patients in the current arm (patient ID, patient object)
/// </summary>
private ConcurrentDictionary<int,
Patient> _patientsCurrentArm = new();
public void DoStuff()
{
const int EXAMPLE_CYCLE = 0;
// Set the number of arms and treatments
int _nArms = 2;
int _nPatients = 5;
// Add patients at baseline to _baselinePatients
for (int i = 0; i < _nPatients; i++) {
Patient patient = new Patient(1);
patient.PatientCovariates.Add(0, new());
_baselinePatients.TryAdd(i, patient);
}
// Try to copy the patients created in the baseline ConcurrentDictionary
for (int i = 0; i < _nArms; i++) {
for (int j = 0; j < _nPatients; j++) {
Patient patObjCopy = (Patient)_baselinePatients[j].Clone();
Patient patObjCopyTwo = (Patient)patObjCopy.Clone();
patObjCopy.PatientCovariates[EXAMPLE_CYCLE].Add("Covariate for patient ", // To mark the arm name and make the patient struct different
j.ToString() +
" in arm " +
i.ToString());
// Save the patient copy in the _patientsCurrentArm WITHOUT changing the patient in _baselinePatients
_patientsCurrentArm.TryAdd(j, patObjCopy);
}
}
}
internal struct Patient : ICloneable
{
private readonly int _seed; // used when the object is copied to regenerated the Crn
public readonly Random Crn { get; }
/// <summary>
/// Cycle, covariate name, covariate value
/// </summary>
public Dictionary<int,
Dictionary<string,
string>> PatientCovariates
{ get; set; }
/// <summary>
/// Initiates PatientCovariates
/// </summary>
public Patient(int seed)
{
_seed = seed;
Crn = new(_seed);
PatientCovariates = new();
}
/// <summary>
/// Clone patients
/// </summary>
/// <returns></returns>
public readonly object Clone()
{
Patient patient = new() {
// Here, I also want to regenerate the Crn by using _seed, as was done when the patient was constructed
PatientCovariates = this.PatientCovariates.ToDictionary(
entry => entry.Key,
entry => entry.Value.ToDictionary(
innerEntry => innerEntry.Key,
innerEntry => innerEntry.Value
)
)
};
return patient;
}
}
}
Crnobject referenced, or you want to recreate a new one? For the former, why can't you have a separateprivateconstructor that's only used by theClonefunction? For the latter you can use the existing constructor.Dictionary<int, Dictionary<string, string>>rather than some domain specific type is a bit of a code smell. I fail to understand the purpose ofCrn, and there are several other things that seem odd. Perhaps there is some better design for your problem? You generally want your types to have behaviors, and not just being a collection of public properties.