diff --git a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/HowToCloneAList.Tests.csproj b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/HowToCloneAList.Tests.csproj index 22a057f9f9..0dd013a8ac 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/HowToCloneAList.Tests.csproj +++ b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/HowToCloneAList.Tests.csproj @@ -1,7 +1,7 @@ - net7.0 + net10.0 enable enable @@ -9,14 +9,14 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/PizzaTests.cs b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/PizzaTests.cs index 8105f3b552..2d6d22c924 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/PizzaTests.cs +++ b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/PizzaTests.cs @@ -1,4 +1,4 @@ -using FluentAssertions; +using FluentAssertions; namespace HowToCloneAList.Tests { @@ -60,5 +60,29 @@ public void GivenAValidPizza_WhenToStringMethodIsInvoked_ThenToStringMethodMetho expectedOutput.Should().Be(margherita.ToString()); } + + [Fact] + public void GivenAListOfPizzas_WhenProjectedThroughTheCopyConstructor_ThenTheCloneKeepsItsToppings() + { + var pizzas = new List + { + new Pizza + { + Name = "Margherita", + Toppings = new List + { + "Mozzarella", + "Olive oil", + "Basil" + } + } + }; + + List clone = [.. pizzas.Select(p => new Pizza(p))]; + + pizzas[0].Toppings.Clear(); + + clone[0].Toppings.Should().HaveCount(3); + } } -} \ No newline at end of file +} diff --git a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/Tests.cs b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/Tests.cs index 783e150390..fec0ed60e7 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/Tests.cs +++ b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/Tests.cs @@ -56,5 +56,27 @@ public void GivenAValidList_WhenConvertAllMethodIsInvoked_ThenConvertAllMethodRe listClone.Should().BeEquivalentTo(list); } + + [Fact] + public void GivenAValidList_WhenACollectionExpressionIsUsed_ThenTheCollectionExpressionReturnsNewListInstance() + { + var list = new List { "one", "two", "three" }; + + List listClone = [.. list]; + + listClone.Should().BeEquivalentTo(list); + listClone.Should().NotBeSameAs(list); + } + + [Fact] + public void GivenAValidList_WhenGetRangeMethodIsInvoked_ThenGetRangeMethodReturnsNewListInstance() + { + var list = new List { "one", "two", "three" }; + + var listClone = list.GetRange(0, list.Count); + + listClone.Should().BeEquivalentTo(list); + listClone.Should().NotBeSameAs(list); + } } } diff --git a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/ToppingsListTests.cs b/collections-lists/HowToCloneAList/HowToCloneAList.Tests/ToppingsListTests.cs deleted file mode 100644 index 8246bd5f05..0000000000 --- a/collections-lists/HowToCloneAList/HowToCloneAList.Tests/ToppingsListTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using FluentAssertions; - -namespace HowToCloneAList.Tests -{ - public class ToppingsListTests - { - [Fact] - public void GivenAValidToppingsList_WhenCloneMethodIsInvoked_ThenCloneMethodReturnsNewToppingsListInstance() - { - var customToppingsList = new ToppingsList - { - "Mozzarella", - "Olive oil", - "Basil" - }; - - var customToppingsListClone = (ToppingsList)customToppingsList.Clone(); - - customToppingsListClone.Should().BeEquivalentTo(customToppingsList); - } - } -} diff --git a/collections-lists/HowToCloneAList/HowToCloneAList/HowToCloneAList.csproj b/collections-lists/HowToCloneAList/HowToCloneAList/HowToCloneAList.csproj index f02677bf64..dfb40caafc 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList/HowToCloneAList.csproj +++ b/collections-lists/HowToCloneAList/HowToCloneAList/HowToCloneAList.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net10.0 enable enable diff --git a/collections-lists/HowToCloneAList/HowToCloneAList/Pizza.cs b/collections-lists/HowToCloneAList/HowToCloneAList/Pizza.cs index e628c0ecb6..145fdb640b 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList/Pizza.cs +++ b/collections-lists/HowToCloneAList/HowToCloneAList/Pizza.cs @@ -1,4 +1,6 @@ -namespace HowToCloneAList +using System.Diagnostics.CodeAnalysis; + +namespace HowToCloneAList { public class Pizza : ICloneable { @@ -6,14 +8,15 @@ public Pizza() { } + [SetsRequiredMembers] public Pizza(Pizza pizza) { Name = pizza.Name; Toppings = pizza.Toppings.ToList(); } - public string Name { get; set; } - public List Toppings { get; set; } + public required string Name { get; set; } + public required List Toppings { get; set; } public object Clone() { diff --git a/collections-lists/HowToCloneAList/HowToCloneAList/Program.cs b/collections-lists/HowToCloneAList/HowToCloneAList/Program.cs index 8cccaddfbe..ccc2ecbd8e 100644 --- a/collections-lists/HowToCloneAList/HowToCloneAList/Program.cs +++ b/collections-lists/HowToCloneAList/HowToCloneAList/Program.cs @@ -24,22 +24,18 @@ static void Main(string[] args) var toppingsClonedWithConvertAll = toppings .ConvertAll(new Converter(x => x)); - var customToppingsList = new ToppingsList - { - "Mozzarella", - "Olive oil", - "Basil" - }; + List toppingsClonedWithCollectionExpression = [.. toppings]; - var toppingsClonedWithICloneable = (ToppingsList)customToppingsList.Clone(); + var toppingsClonedWithGetRange = toppings.GetRange(0, toppings.Count); Console.WriteLine("Original list: " + string.Join(", ", toppings)); Console.WriteLine("Cloned with Constructor: " + string.Join(", ", toppingsClonedWithConstructor)); Console.WriteLine("Cloned with CopyTo: " + string.Join(", ", toppingsClonedWithCopyTo)); Console.WriteLine("Cloned with AddRange: " + string.Join(", ", toppingsClonedWithAddRange)); Console.WriteLine("Cloned with ToList: " + string.Join(", ", toppingsClonedWithToList)); - Console.WriteLine("Cloned with ConverAll: " + string.Join(", ", toppingsClonedWithConvertAll)); - Console.WriteLine("Cloned with ICloneable: " + string.Join(", ", toppingsClonedWithICloneable)); + Console.WriteLine("Cloned with ConvertAll: " + string.Join(", ", toppingsClonedWithConvertAll)); + Console.WriteLine("Cloned with a collection expression: " + string.Join(", ", toppingsClonedWithCollectionExpression)); + Console.WriteLine("Cloned with GetRange: " + string.Join(", ", toppingsClonedWithGetRange)); var pizzas = new List { @@ -74,15 +70,10 @@ static void Main(string[] args) pizzasClonedWithICloneable.Add((Pizza)pizza.Clone()); } - var pizzasClonedWithCopyConstructor = new List(); - - foreach (var pizza in pizzas) - { - pizzasClonedWithCopyConstructor.Add(new Pizza(pizza)); - } + List pizzasClonedWithCopyConstructor = [.. pizzas.Select(p => new Pizza(p))]; var margherita = pizzas - .FirstOrDefault(x => x.Name == "Margherita"); + .First(x => x.Name == "Margherita"); margherita.Toppings.Clear(); diff --git a/collections-lists/HowToCloneAList/HowToCloneAList/ToppingsList.cs b/collections-lists/HowToCloneAList/HowToCloneAList/ToppingsList.cs deleted file mode 100644 index 68ca91ac83..0000000000 --- a/collections-lists/HowToCloneAList/HowToCloneAList/ToppingsList.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace HowToCloneAList -{ - public class ToppingsList : List, ICloneable - { - public object Clone() - { - return this.MemberwiseClone(); - } - } -}