Skip to content

Commit 7dfab24

Browse files
UsingStaticInCSharp: net10.0, real output tests, global using static and member precedence examples (#2354)
1 parent 4438423 commit 7dfab24

13 files changed

Lines changed: 146 additions & 38 deletions

File tree

‎csharp-basic-topics/UsingStaticInCSharp/UsingStaticInCSharp.Tests/UsingStaticInCSharp.Tests.csproj‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77

88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
13-
<PackageReference Include="Moq" Version="4.18.2" />
14-
<PackageReference Include="xunit" Version="2.4.2" />
15-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
13+
<PackageReference Include="xunit" Version="2.9.3" />
14+
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.1">
1615
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1716
<PrivateAssets>all</PrivateAssets>
1817
</PackageReference>
19-
<PackageReference Include="coverlet.collector" Version="3.1.2">
18+
<PackageReference Include="coverlet.collector" Version="10.1.0">
2019
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2120
<PrivateAssets>all</PrivateAssets>
2221
</PackageReference>
Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,106 @@
1-
using Moq;
2-
31
namespace UsingStaticInCSharp.Tests;
2+
43
public class UsingStaticUnitTest
54
{
5+
private static string CaptureOutput(Action invoke)
6+
{
7+
var original = Console.Out;
8+
using var writer = new StringWriter();
9+
Console.SetOut(writer);
10+
try
11+
{
12+
invoke();
13+
}
14+
finally
15+
{
16+
Console.SetOut(original);
17+
}
18+
19+
return writer.ToString();
20+
}
21+
22+
[Fact]
23+
public void GivenAStaticMethodFromClassA_WhenCalledByUsingStaticFeature_ThenItRuns()
24+
{
25+
var output = CaptureOutput(() => new MethodsAndProperties.Caller().Invoke());
26+
27+
Assert.Contains("MethodsAndProperties.ClassA.MethodA() called", output);
28+
Assert.Contains("MethodsAndProperties.ClassA.MethodB() called", output);
29+
}
30+
31+
[Fact]
32+
public void GivenAnEnum_WhenItemsAreUsedByUsingStaticFeature_ThenTheyResolve()
33+
{
34+
var output = CaptureOutput(() => new Enums.Caller().Invoke());
35+
36+
Assert.Contains("The enum items are User, Admin", output);
37+
}
38+
39+
[Fact]
40+
public void GivenStaticConstants_WhenUsedByUsingStaticFeature_ThenTheyResolve()
41+
{
42+
var output = CaptureOutput(() => new Constants.Caller().Invoke());
43+
44+
Assert.Contains("Pending, InProgress, Completed", output);
45+
}
46+
47+
[Fact]
48+
public void GivenANestedClass_WhenCalledByUsingStaticFeature_ThenItRuns()
49+
{
50+
var output = CaptureOutput(() => new NestedTypeMembers.Caller().Invoke());
51+
52+
Assert.Contains("NestedTypeMembers.ClassA.ClassB.MethodA() called", output);
53+
Assert.Contains("NestedTypeMembers.ClassA.ClassB.MethodB() called", output);
54+
}
55+
656
[Fact]
7-
public void GivenAStaticConstant_WhenCalledByUsingStaticFeature_ShouldBeInvoked()
57+
public void GivenTheOuterClass_WhenImportedByUsingStatic_ThenTheNestedClassNeedsNoPrefix()
858
{
9-
var mock = new Mock<Constants.Caller>();
10-
mock.Object.Invoke();
59+
var output = CaptureOutput(() => new NestedTypeMembers.OuterTypeCaller().Invoke());
1160

12-
mock.Verify(x => x.Invoke());
61+
Assert.Contains("NestedTypeMembers.ClassA.ClassB.MethodA() called", output);
62+
Assert.Contains("NestedTypeMembers.ClassA.ClassB.MethodB() called", output);
1363
}
1464

1565
[Fact]
16-
public void GivenANestedClassFromSampleClassOne_WhenCalledByUsingStaticFeature_ShouldBeInvoked()
66+
public void GivenAnExtensionMethodInDifferentNamespace_WhenImportedByUsingStatic_ThenItIsFound()
1767
{
18-
var mock = new Mock<NestedTypeMembers.Caller>();
19-
mock.Object.Invoke();
68+
var output = CaptureOutput(() => new ExtensionMethods.Caller().Invoke());
2069

21-
mock.Verify(x => x.Invoke());
70+
Assert.Contains("The sum is 3", output);
2271
}
2372

2473
[Fact]
25-
public void GivenAStaticMethodFromClassA_WhenCalledByUsingStaticFeature_ShouldBeInvoked()
74+
public void GivenADerivedClass_WhenItsOwnStaticMethodIsCalledByUsingStatic_ThenItRuns()
2675
{
27-
var mock = new Mock<MethodsAndProperties.Caller>();
28-
mock.Object.Invoke();
76+
var output = CaptureOutput(() => new BaseClassMembers.Caller().Invoke());
2977

30-
mock.Verify(x => x.Invoke());
78+
Assert.Contains("BaseClassMembers.ClassB.MethodB() called", output);
3179
}
3280

3381
[Fact]
34-
public void GivenAAmbiguityMethodFromClassAAndClassB_WhenCalledByItsClassName_ShouldBeInvoked()
82+
public void GivenTwoClassesWithTheSameMethod_WhenCalledByClassName_ThenBothRun()
3583
{
36-
var mock = new Mock<Ambiguity.Caller>();
37-
mock.Object.Invoke();
84+
var output = CaptureOutput(() => new Ambiguity.Caller().Invoke());
3885

39-
mock.Verify(x => x.Invoke());
86+
Assert.Contains("Ambiguity.ClassA.Method() called", output);
87+
Assert.Contains("Ambiguity.ClassB.Method() called", output);
4088
}
4189

4290
[Fact]
43-
public void GivenAEnum_WhenCalledByUsingStaticFeature_ShouldBeInvoked()
91+
public void GivenAGlobalUsingStatic_WhenMathMembersAreCalledWithoutTypeName_ThenTheyResolve()
4492
{
45-
var mock = new Mock<Enums.Caller>();
46-
mock.Object.Invoke();
93+
var output = CaptureOutput(() => new GlobalUsingStatic.Caller().Invoke());
4794

48-
mock.Verify(x => x.Invoke());
95+
Assert.Contains("The hypotenuse is 5", output);
96+
Assert.Contains("The best score is 9", output);
4997
}
5098

5199
[Fact]
52-
public void GivenAnExtensionMethodInDifferentNamespace_WhenCalledByUsingStaticFeature_ShouldBeInvoked()
100+
public void GivenAMemberWithTheSameName_WhenCalledUnqualified_ThenTheEnclosingTypeWins()
53101
{
54-
var mock = new Mock<ExtensionMethods.Caller>();
55-
mock.Object.Invoke();
102+
var output = CaptureOutput(() => new MemberPrecedence.Caller().Invoke());
56103

57-
mock.Verify(x => x.Invoke());
104+
Assert.Contains("Describe() returned Caller.Describe()", output);
58105
}
59-
}
106+
}

‎csharp-basic-topics/UsingStaticInCSharp/UsingStaticInCSharp/Constants/Caller.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ public class Caller
55
{
66
public virtual void Invoke()
77
{
8-
Console.WriteLine("The contants are {0}, {1}, {2}", Pending, InProgress, Completed);
8+
Console.WriteLine("The constants are {0}, {1}, {2}", Pending, InProgress, Completed);
99
}
1010
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using static UsingStaticInCSharp.GlobalUsingStatic.Scores;
2+
3+
namespace UsingStaticInCSharp.GlobalUsingStatic;
4+
public class Caller
5+
{
6+
public virtual void Invoke()
7+
{
8+
var hypotenuse = Sqrt(Pow(3, 2) + Pow(4, 2));
9+
Console.WriteLine("The hypotenuse is {0}", hypotenuse);
10+
11+
var best = Scores.Max(3, 9);
12+
Console.WriteLine("The best score is {0}", best);
13+
14+
// Error CS0121 The call is ambiguous
15+
// between the following methods or properties:
16+
// 'System.Math.Max(int, int)' and 'UsingStaticInCSharp.GlobalUsingStatic.Scores.Max(int, int)'
17+
// var best = Max(3, 9);
18+
}
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
global using static System.Math;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace UsingStaticInCSharp.GlobalUsingStatic;
2+
public static class Scores
3+
{
4+
public static int Max(int first, int second) => first > second ? first : second;
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using static UsingStaticInCSharp.MemberPrecedence.ClassA;
2+
3+
namespace UsingStaticInCSharp.MemberPrecedence;
4+
public class Caller
5+
{
6+
public virtual void Invoke()
7+
{
8+
Console.WriteLine("Describe() returned {0}", Describe());
9+
}
10+
11+
private static string Describe() => "Caller.Describe()";
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace UsingStaticInCSharp.MemberPrecedence;
2+
public static class ClassA
3+
{
4+
public static string Describe() => "ClassA.Describe()";
5+
}

‎csharp-basic-topics/UsingStaticInCSharp/UsingStaticInCSharp/NestedTypeMembers/Caller.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ public class Caller
55
{
66
public virtual void Invoke()
77
{
8+
MethodA();
89
MethodB();
910
}
1011
}

‎csharp-basic-topics/UsingStaticInCSharp/UsingStaticInCSharp/NestedTypeMembers/ClassA.cs‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
namespace UsingStaticInCSharp.NestedTypeMembers;
2-
public static class ClassA
2+
public class ClassA
33
{
4-
public static class ClassB
4+
public class ClassB
55
{
6+
public static void MethodA()
7+
{
8+
Console.WriteLine("NestedTypeMembers.ClassA.ClassB.MethodA() called");
9+
}
10+
611
public static void MethodB()
712
{
813
Console.WriteLine("NestedTypeMembers.ClassA.ClassB.MethodB() called");

0 commit comments

Comments
 (0)