Skip to content

Commit 882fd66

Browse files
committed
Null billion dollar
1 parent 16debd7 commit 882fd66

File tree

4 files changed

+439
-0
lines changed

4 files changed

+439
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.4.32916.344
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NullBillionDollar", "NullBillionDollar\NullBillionDollar.csproj", "{7E148EA3-B286-4E7B-BDAF-C41D80A4F1DB}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{7E148EA3-B286-4E7B-BDAF-C41D80A4F1DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{7E148EA3-B286-4E7B-BDAF-C41D80A4F1DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{7E148EA3-B286-4E7B-BDAF-C41D80A4F1DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{7E148EA3-B286-4E7B-BDAF-C41D80A4F1DB}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {C7B1C2E4-EA1E-4F83-9441-3E2B678EA7E4}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<LangVersion>preview</LangVersion>
8+
</PropertyGroup>
9+
10+
</Project>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#nullable enable
2+
using System.Text.Json;
3+
using System.Text.Json.Nodes;
4+
5+
// Null check in functions
6+
DoSomething("Hello");
7+
static void DoSomething(string? s)
8+
{
9+
ArgumentNullException.ThrowIfNull(s);
10+
}
11+
12+
// Null coalescing operator
13+
Console.WriteLine(IntoNotNull(null));
14+
Console.WriteLine(MultipleIntoNotNull(null, "FooBar"));
15+
static string IntoNotNull(string? maybeNullString) => maybeNullString ?? "default";
16+
static string MultipleIntoNotNull(string? maybeNullString, string? second)
17+
=> maybeNullString ?? second ?? "default";
18+
19+
// Null coalescing operator with throw expression
20+
Console.WriteLine(ThrowIfNull("FooBar"));
21+
static string ThrowIfNull(string? maybeNullString) => maybeNullString ?? throw new ArgumentNullException(null, nameof(maybeNullString));
22+
23+
ThrowIfNullStatement("FooBar");
24+
static void ThrowIfNullStatement(string? maybeNullString) => _ = maybeNullString ?? throw new ArgumentNullException(null, nameof(maybeNullString));
25+
26+
// Null coalescing assignment operator
27+
List<int>? numbers = null;
28+
Push(42);
29+
Push(43);
30+
Console.WriteLine(JsonSerializer.Serialize(numbers));
31+
void Push(int number)
32+
{
33+
numbers ??= new List<int>();
34+
numbers.Add(number);
35+
}
36+
37+
Console.WriteLine(GetNameOfHero(42));
38+
Console.WriteLine(GetNameOfHero(44));
39+
string GetNameOfHero(int id)
40+
{
41+
var heroes = JsonNode.Parse("""
42+
{
43+
"theBoys": [
44+
{ "id": 42, "name": "Starlight", "canFly": false },
45+
{ "id": 43, "name": "Homelander", "canFly": true }
46+
]
47+
}
48+
""");
49+
50+
var theBoys = heroes?["theBoys"] as JsonArray;
51+
// +---- Null conditional indexer
52+
// | +---- Null conditional operator
53+
// | | +---- Null coalescing operator
54+
// v v v
55+
return theBoys?.FirstOrDefault(b => ((b?["id"])?.GetValue<int?>() ?? -1) == id)?["name"]?.GetValue<string?>() ?? "not found";
56+
}
57+
58+
Console.WriteLine(GetNameOfHeroForgiving(42));
59+
Console.WriteLine(GetNameOfHeroForgiving(44));
60+
string GetNameOfHeroForgiving(int id)
61+
{
62+
var heroes = JsonNode.Parse("""
63+
{
64+
"theBoys": [
65+
{ "id": 42, "name": "Starlight", "canFly": false },
66+
{ "id": 43, "name": "Homelander", "canFly": true }
67+
]
68+
}
69+
""");
70+
71+
var theBoys = heroes!["theBoys"] as JsonArray;
72+
73+
// Assumption: We KNOW that theBoys is not null and that properties id and name exist
74+
// -> We can use the ! operator to tell the compiler that we know what we are doing
75+
return theBoys!.FirstOrDefault(b => (b!["id"])!.GetValue<int>() == id)?["name"]!.GetValue<string?>() ?? "not found";
76+
}
77+
78+
Console.WriteLine(NullPattern1(null));
79+
string NullPattern1(string? input)
80+
{
81+
// Note: Null pattern ignores overloads of == operator
82+
if (input is null)
83+
{
84+
return "default";
85+
}
86+
87+
return input;
88+
}
89+
90+
Console.WriteLine(NullPattern2(null));
91+
string NullPattern2(string? input)
92+
{
93+
if (input is not null)
94+
{
95+
return input;
96+
}
97+
98+
return "default";
99+
}

0 commit comments

Comments
 (0)