Skip to content

Commit 73ea3dc

Browse files
committed
Always-valid-smart-enums are considered equal if the object references are equal.
1 parent 9c81745 commit 73ea3dc

File tree

3 files changed

+73
-69
lines changed

3 files changed

+73
-69
lines changed

samples/Thinktecture.Runtime.Extensions.Samples/SmartEnums/SmartEnumDemos.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System;
12
using System.ComponentModel.DataAnnotations;
3+
using System.Globalization;
24
using Serilog;
35

46
namespace Thinktecture.SmartEnums;
@@ -65,6 +67,39 @@ private static void DemoForNonValidatableEnum(ILogger logger)
6567
ProductType.Housewares, static l => "Switch with Func<T>: Housewares");
6668

6769
logger.Information(returnValue);
70+
71+
var formatted = ProductGroup.Apple.ToString("000", CultureInfo.InvariantCulture); // 001
72+
logger.Information("Formatted: {Formatted}", formatted);
73+
74+
var comparison = ProductGroup.Apple.CompareTo(ProductGroup.Orange); // -1
75+
logger.Information("Comparison: {Comparison}", comparison);
76+
77+
logger.Information("==== Demo for abstract static members ====");
78+
79+
PrintAllItems<ProductType, string>(logger);
80+
81+
Get<ProductType, string>(logger, "Groceries");
82+
}
83+
84+
private static void PrintAllItems<T, TKey>(ILogger logger)
85+
where T : IEnum<TKey, T>, IEnum<TKey>
86+
where TKey : notnull
87+
{
88+
logger.Information("Print all items of '{Name}':", typeof(T).Name);
89+
90+
foreach (var item in T.Items)
91+
{
92+
logger.Information("Item: {Item}", item);
93+
}
94+
}
95+
96+
private static void Get<T, TKey>(ILogger logger, TKey key)
97+
where T : IEnum<TKey, T>, IEnum<TKey>
98+
where TKey : notnull
99+
{
100+
var item = T.Get(key);
101+
102+
logger.Information("Key '{Key}' => '{Item}'", key, item);
68103
}
69104

70105
private static void DemoForValidatableEnum(ILogger logger)

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private void GenerateEnum()
124124
GenerateImplicitConversion();
125125
GenerateExplicitConversion();
126126
GenerateEqualityOperators();
127-
GenerateTypedEquals();
127+
GenerateEquals();
128128

129129
_sb.Append($@"
130130
@@ -459,16 +459,26 @@ private void GenerateEqualityOperators()
459459
public static bool operator ==({_state.TypeFullyQualifiedNullAnnotated} item1, {_state.TypeFullyQualifiedNullAnnotated} item2)
460460
{{");
461461

462-
if (_state.IsReferenceType)
462+
if (_state.IsValidatable)
463463
{
464-
_sb.Append(@"
464+
if (_state.IsReferenceType)
465+
{
466+
_sb.Append(@"
465467
if (item1 is null)
466468
return item2 is null;
467469
");
470+
}
471+
472+
_sb.Append(@"
473+
return item1.Equals(item2);");
474+
}
475+
else
476+
{
477+
_sb.Append(@"
478+
return global::System.Object.ReferenceEquals(item1, item2);");
468479
}
469480

470481
_sb.Append($@"
471-
return item1.Equals(item2);
472482
}}
473483
474484
/// <summary>
@@ -527,17 +537,19 @@ private void GenerateExplicitConversion()
527537
}}");
528538
}
529539

530-
private void GenerateTypedEquals()
540+
private void GenerateEquals()
531541
{
532542
_sb.Append($@"
533543
534544
/// <inheritdoc />
535545
public bool Equals({_state.TypeFullyQualifiedNullAnnotated} other)
536546
{{");
537547

538-
if (_state.IsReferenceType)
548+
if (_state.IsValidatable)
539549
{
540-
_sb.Append(@"
550+
if (_state.IsReferenceType)
551+
{
552+
_sb.Append(@"
541553
if (other is null)
542554
return false;
543555
@@ -547,19 +559,24 @@ public bool Equals({_state.TypeFullyQualifiedNullAnnotated} other)
547559
if (global::System.Object.ReferenceEquals(this, other))
548560
return true;
549561
");
550-
}
562+
}
551563

552-
if (_state.IsValidatable)
553-
{
554564
_sb.Append(@"
555565
if (this.IsValid != other.IsValid)
556566
return false;
557567
");
568+
569+
_sb.Append($@"
570+
return {EnumSourceGeneratorState.KEY_EQUALITY_COMPARER_NAME}.Equals(this.{_state.KeyProperty.Name}, other.{_state.KeyProperty.Name});");
571+
}
572+
else
573+
{
574+
_sb.Append(@"
575+
return global::System.Object.ReferenceEquals(this, other);");
558576
}
559577

560-
_sb.Append($@"
561-
return {EnumSourceGeneratorState.KEY_EQUALITY_COMPARER_NAME}.Equals(this.{_state.KeyProperty.Name}, other.{_state.KeyProperty.Name});
562-
}}");
578+
_sb.Append(@"
579+
}");
563580
}
564581

565582
private void GenerateGetLookup()

test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/SourceGeneratorTests/EnumSourceGeneratorTests.cs

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
165165
/// <returns><c>true</c> if items are equal; otherwise <c>false</c>.</returns>
166166
public static bool operator ==(global::Thinktecture.Tests.TestEnum? item1, global::Thinktecture.Tests.TestEnum? item2)
167167
{
168-
if (item1 is null)
169-
return item2 is null;
170-
171-
return item1.Equals(item2);
168+
return global::System.Object.ReferenceEquals(item1, item2);
172169
}
173170
174171
/// <summary>
@@ -185,16 +182,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
185182
/// <inheritdoc />
186183
public bool Equals(global::Thinktecture.Tests.TestEnum? other)
187184
{
188-
if (other is null)
189-
return false;
190-
191-
if (!global::System.Object.ReferenceEquals(GetType(), other.GetType()))
192-
return false;
193-
194-
if (global::System.Object.ReferenceEquals(this, other))
195-
return true;
196-
197-
return KeyEqualityComparer.Equals(this.Key, other.Key);
185+
return global::System.Object.ReferenceEquals(this, other);
198186
}
199187
200188
/// <inheritdoc />
@@ -640,10 +628,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
640628
/// <returns><c>true</c> if items are equal; otherwise <c>false</c>.</returns>
641629
public static bool operator ==(global::Thinktecture.Tests.TestEnum? item1, global::Thinktecture.Tests.TestEnum? item2)
642630
{
643-
if (item1 is null)
644-
return item2 is null;
645-
646-
return item1.Equals(item2);
631+
return global::System.Object.ReferenceEquals(item1, item2);
647632
}
648633
649634
/// <summary>
@@ -660,16 +645,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
660645
/// <inheritdoc />
661646
public bool Equals(global::Thinktecture.Tests.TestEnum? other)
662647
{
663-
if (other is null)
664-
return false;
665-
666-
if (!global::System.Object.ReferenceEquals(GetType(), other.GetType()))
667-
return false;
668-
669-
if (global::System.Object.ReferenceEquals(this, other))
670-
return true;
671-
672-
return KeyEqualityComparer.Equals(this.Key, other.Key);
648+
return global::System.Object.ReferenceEquals(this, other);
673649
}
674650
675651
/// <inheritdoc />
@@ -1048,10 +1024,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
10481024
/// <returns><c>true</c> if items are equal; otherwise <c>false</c>.</returns>
10491025
public static bool operator ==(global::TestEnum? item1, global::TestEnum? item2)
10501026
{
1051-
if (item1 is null)
1052-
return item2 is null;
1053-
1054-
return item1.Equals(item2);
1027+
return global::System.Object.ReferenceEquals(item1, item2);
10551028
}
10561029
10571030
/// <summary>
@@ -1068,16 +1041,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
10681041
/// <inheritdoc />
10691042
public bool Equals(global::TestEnum? other)
10701043
{
1071-
if (other is null)
1072-
return false;
1073-
1074-
if (!global::System.Object.ReferenceEquals(GetType(), other.GetType()))
1075-
return false;
1076-
1077-
if (global::System.Object.ReferenceEquals(this, other))
1078-
return true;
1079-
1080-
return KeyEqualityComparer.Equals(this.Key, other.Key);
1044+
return global::System.Object.ReferenceEquals(this, other);
10811045
}
10821046
10831047
/// <inheritdoc />
@@ -1452,10 +1416,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
14521416
/// <returns><c>true</c> if items are equal; otherwise <c>false</c>.</returns>
14531417
public static bool operator ==(global::Thinktecture.Tests.TestEnum? item1, global::Thinktecture.Tests.TestEnum? item2)
14541418
{
1455-
if (item1 is null)
1456-
return item2 is null;
1457-
1458-
return item1.Equals(item2);
1419+
return global::System.Object.ReferenceEquals(item1, item2);
14591420
}
14601421
14611422
/// <summary>
@@ -1472,16 +1433,7 @@ public static bool TryGet([global::System.Diagnostics.CodeAnalysis.AllowNull] st
14721433
/// <inheritdoc />
14731434
public bool Equals(global::Thinktecture.Tests.TestEnum? other)
14741435
{
1475-
if (other is null)
1476-
return false;
1477-
1478-
if (!global::System.Object.ReferenceEquals(GetType(), other.GetType()))
1479-
return false;
1480-
1481-
if (global::System.Object.ReferenceEquals(this, other))
1482-
return true;
1483-
1484-
return KeyEqualityComparer.Equals(this.Key, other.Key);
1436+
return global::System.Object.ReferenceEquals(this, other);
14851437
}
14861438
14871439
/// <inheritdoc />

0 commit comments

Comments
 (0)