public static void B_ChangeOfFieldWithValueTypeForComplexValueTypePassedByValueIsNotTakeEffectInCaller()
        {
            var sourceTrainer   = new TrainerValueType("Dan", 2);
            var expectedTrainer = sourceTrainer;

            Trace.TraceInformation(
                $"Create a variable of a complex value type. Type: TrainerValueType, value = '{sourceTrainer}'.");

            Trace.TraceInformation("Pass it to the method, which increment property 'Experience' (value type - int).");
            var changedTrainer = TypesChanger.IncrementExperienceOfTrainer(sourceTrainer);

            Trace.TraceInformation(
                "Expected, that the value in the caller is not affected, but the value in the method, " +
                "which was called, is incremented. It occurs because the called method got a copy of a complex value type.");

            Trace.TraceInformation(
                $"Compare the source experience with expected (Should be the same): source = '{sourceTrainer.Experience}'; expected = '{expectedTrainer.Experience}'.");
            sourceTrainer.Experience
            .Should()
            .Be(expectedTrainer.Experience);

            Trace.TraceInformation(
                $"Compare changed experience with the original (The changed value should be greater than the original): changed = '{changedTrainer.Experience}'; original = '{sourceTrainer.Experience}'.");
            changedTrainer.Experience
            .Should()
            .BeGreaterThan(sourceTrainer.Experience);
        }
        public static void C_ChangeOfFieldWithReferenceTypeForComplexValueTypePassedByValueIsNotTakeEffectInCaller()
        {
            var sourceTrainer   = new TrainerValueType("Dan", 2);
            var expectedTrainer = sourceTrainer;

            Trace.TraceInformation(
                $"Create a variable of a complex value type with empty field (type of field - reference). Type: TrainerValueType (without trainees), value = '{sourceTrainer}'.");

            Trace.TraceInformation(
                "Pass it to the method, which add trainees (referenceType type - TraineeReferenceType).");
            var changedTrainer = TypesChanger.AssignTraineesToTrainer(sourceTrainer);

            Trace.TraceInformation(
                "Expected, that the value in the caller is not affected, but the trainer in the method, " +
                "which was called, has trainees. It occurs because the called method got a copy of a trainer " +
                "no matter the field 'Trainees' is a reference type, the field does not reference to the source reference.");

            Trace.TraceInformation(
                "Compare trainees of the source trainer with expected (Should be the same and empty): " +
                $"source = '{string.Join("; ", sourceTrainer.Trainees.Select(trainee => trainee.ToString()))}'; " +
                $"expected = '{string.Join("; ", expectedTrainer.Trainees.Select(trainee => trainee.ToString()))}'.");
            // ↑ We use LINQ query here (Select method) we will go deeper with it later, just ignore it for now.

            sourceTrainer.Trainees
            .Should()
            .BeEmpty();
            sourceTrainer.Trainees
            .Should()
            .BeSameAs(expectedTrainer.Trainees);

            Trace.TraceInformation(
                "The changed trainer should have trainees: " +
                $"changed trainees = '{string.Join("; ", changedTrainer.Trainees.Select(trainee => trainee.ToString()))}'.");
            changedTrainer.Trainees
            .Should()
            .OnlyContain(trainee => trainee != null);
        }
        public static TrainerValueType AssignTraineesToTrainer(TrainerValueType trainer)
        {
            trainer.Trainees = new[] { new TraineeReferenceType("Bill", 9), new TraineeReferenceType("Bob", 15) };

            return(trainer);
        }
        public static TrainerValueType IncrementExperienceOfTrainer(TrainerValueType trainer)
        {
            trainer.Experience++;

            return(trainer);
        }