Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions csharp-basic-topics/ParamsKeyword/ParamsKeyword/Basket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ParamsKeyword;

public class Basket
{
public void Store(params string[] items)
=> Console.WriteLine($"Array overload: {items.Length} items");

public void Store(params ReadOnlySpan<string> items)
=> Console.WriteLine($"Span overload: {items.Length} items");
}
Original file line number Diff line number Diff line change
@@ -1,82 +1,135 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;

namespace ParamsKeyword
namespace ParamsKeyword;

[TestFixture]
public class CallParamsMethodUnitTest
{
[TestFixture]
public class CallParamsMethodUnitTest
private StringWriter _writer = null!;

[SetUp]
public void CaptureConsole()
{
_writer = new StringWriter();
Console.SetOut(_writer);
}

[TearDown]
public void ReleaseConsole() => _writer.Dispose();

private string[] Lines() =>
_writer.ToString().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);

[Test]
public void WhenCommaDelimitedListOfArgs_ThenReturnsValidResult()
{
var shoppingList = new ShoppingList();
shoppingList.Add("Bananas", "Grapes", "Ham", "Cheese");
shoppingList.Add("Headphones");

string[] expectedResult =
[
"Added: Bananas",
"Added: Grapes",
"Added: Ham",
"Added: Cheese",
"Added: Headphones",
];

Assert.That(Lines(), Is.EqualTo(expectedResult));
}

[Test]
public void WhenCollectionArgument_ThenReturnsValidResult()
{
var shoppingList = new ShoppingList();
string[] groceries = ["Bananas", "Grapes", "Ham", "Cheese"];
shoppingList.Add(groceries);

string[] expectedResult = ["Added: Bananas", "Added: Grapes", "Added: Ham", "Added: Cheese"];

Assert.That(Lines(), Is.EqualTo(expectedResult));
}

[Test]
public void WhenNoArguments_ThenReturnsValidResult()
{
var shoppingList = new ShoppingList();
shoppingList.Add();

Assert.That(_writer.ToString(), Is.Empty);
}

[Test]
public void WhenNullArgument_ThenThrowsAnException()
{
var shoppingList = new ShoppingList();
string[]? groceries = default;

#pragma warning disable CS8604 // Possible null reference argument.
Assert.Throws<NullReferenceException>(() => shoppingList.Add(groceries));
#pragma warning restore CS8604
}

[Test]
public void WhenParamsIEnumerable_ThenAcceptsListAndLinqResult()
{
var shoppingList = new ShoppingList();
shoppingList.AddRange("Milk", "Eggs");

List<string> pantry = ["Rice", "Beans", "Pasta"];
shoppingList.AddRange(pantry.Where(item => item.StartsWith('B')));

string[] expectedResult = ["Added: Milk", "Added: Eggs", "Added: Beans"];

Assert.That(Lines(), Is.EqualTo(expectedResult));
}

[Test]
public void WhenParamsReadOnlySpan_ThenCountsArguments()
{
var shoppingList = new ShoppingList();

Assert.That(shoppingList.Count("Bananas", "Grapes", "Ham"), Is.EqualTo(3));
Assert.That(shoppingList.Count(), Is.EqualTo(0));
}

[Test]
public void WhenOtherParametersBeforeParams_ThenTheRestGoToParams()
{
Assert.That(ParamsSignatures.StringBeforeStringParams("Required", "And", "Free"), Is.EqualTo("Required + 2"));
Assert.That(ParamsSignatures.ArrayBeforeParams(["Required", "Array"], "And", "Free", "Arguments"), Is.EqualTo("2 + 3"));
Assert.That(ParamsSignatures.ArrayBeforeParams(["Required", "Array"], ["And", "Array", "For Params"]), Is.EqualTo("2 + 3"));
Assert.That(ParamsSignatures.OtherArgumentsBeforeParams(2, true, "Yeah", "Now", "All good"), Is.EqualTo("2, True, 3"));
Assert.That(ParamsSignatures.UseParamsWithNamedArguments(firstArgument: 10, items: ["Now", "all", "good"]), Is.EqualTo("10 + 3"));
}

[Test]
public void WhenArrayAndSpanOverloads_ThenListPicksSpanAndArrayPicksArray()
{
var basket = new Basket();
basket.Store("Bananas", "Grapes");
string[] groceries = ["Bananas", "Grapes"];
basket.Store(groceries);

string[] expectedResult = ["Span overload: 2 items", "Array overload: 2 items"];

Assert.That(Lines(), Is.EqualTo(expectedResult));
}

[Test]
public void WhenArrayPassedToParamsObject_ThenOnlyReferenceTypeArraysExpand()
{
string[] names = ["Bananas", "Grapes"];
int[] quantities = [3, 5];

Assert.That(ParamsSignatures.CountObjects(names), Is.EqualTo(2));
Assert.That(ParamsSignatures.CountObjects(quantities), Is.EqualTo(1));
}

[Test]
public void WhenNamedArgumentWithSingleValue_ThenCompilesAsOneElementArray()
{
[Test]
public void WhenCommaDelimitedListOfArgs_ThenReturnsValidResult()
{
//capture the console output
using var writer = new StringWriter();
Console.SetOut(writer);

var shoppingList = new ShoppingList();
shoppingList.Add("Bananas", "Grapes", "Ham", "Cheese");
shoppingList.Add("Headphones");

var expectedResult = new string[] {
"Added: Bananas",
"Added: Grapes",
"Added: Ham",
"Added: Cheese",
"Added: Headphones",
};

Assert.AreEqual(expectedResult, writer.ToString().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries));
}

[Test]
public void WhenCollectionArgument_ThenReturnsValidResult()
{
//capture the console output
using var writer = new StringWriter();
Console.SetOut(writer);

var shoppingList = new ShoppingList();
var groceries = new [] { "Bananas", "Grapes", "Ham", "Cheese" };
shoppingList.Add(groceries);

var expectedResult = new string[] {
"Added: Bananas",
"Added: Grapes",
"Added: Ham",
"Added: Cheese"
};

Assert.AreEqual(expectedResult, writer.ToString().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries));
}

[Test]
public void WhenNoArguments_ThenReturnsValidResult()
{
//capture the console output
using var writer = new StringWriter();
Console.SetOut(writer);

var shoppingList = new ShoppingList();
shoppingList.Add();

Assert.AreEqual(string.Empty, writer.ToString());
}

[Test]
public void WhenNullArgument_ThenThrowsAnException()
{
//capture the console output
using var writer = new StringWriter();
Console.SetOut(writer);

var shoppingList = new ShoppingList();
string[]? groceries = default;

#pragma warning disable CS8604 // Possible null reference argument.
Assert.Throws<NullReferenceException>(()=>shoppingList.Add(groceries));
#pragma warning restore CS8604 // Possible null reference argument.
}
Assert.That(ParamsSignatures.UseParamsWithNamedArguments(firstArgument: 10, items: "Single"), Is.EqualTo("10 + 1"));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
<PackageReference Include="NUnit" Version="5.0.0" />
<PackageReference Include="NUnit3TestAdapter" Version="6.3.1" />
<PackageReference Include="coverlet.collector" Version="10.1.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace ParamsKeyword;

public static class ParamsSignatures
{
public static string StringBeforeStringParams(string requiredStringArgument, params string[] items)
=> $"{requiredStringArgument} + {items.Length}";

public static string ArrayBeforeParams(string[] requiredArray, params string[] items)
=> $"{requiredArray.Length} + {items.Length}";

public static string OtherArgumentsBeforeParams(int requiredParam, bool optionalBool = true, params string[] items)
=> $"{requiredParam}, {optionalBool}, {items.Length}";

public static string UseParamsWithNamedArguments(int firstArgument, params string[] items)
=> $"{firstArgument} + {items.Length}";

public static int CountObjects(params object[] items) => items.Length;
}
25 changes: 16 additions & 9 deletions csharp-basic-topics/ParamsKeyword/ParamsKeyword/ShoppingList.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
using System;
namespace ParamsKeyword;

namespace ParamsKeyword
public class ShoppingList
{
public class ShoppingList
public void Add(params string[] items)
{
public void Add(params string[] items)
foreach (var item in items)
{
foreach (var item in items)
{
Console.WriteLine($"Added: {item}");
}
Console.WriteLine($"Added: {item}");
}
}
}

public void AddRange(params IEnumerable<string> items)
{
foreach (var item in items)
{
Console.WriteLine($"Added: {item}");
}
}

public int Count(params ReadOnlySpan<string> items) => items.Length;
}
Loading