Skip to content

Commit bd757ee

Browse files
authored
Nullable: System.Enum
1 parent d073a17 commit bd757ee

File tree

2 files changed

+56
-58
lines changed

2 files changed

+56
-58
lines changed

src/System.Private.CoreLib/shared/System/Enum.cs

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
#nullable enable
56
using System.Diagnostics;
67
using System.Globalization;
78
using System.Reflection;
@@ -72,8 +73,7 @@ private string ValueToString()
7273
case CorElementType.ELEMENT_TYPE_U:
7374
return Unsafe.As<byte, UIntPtr>(ref data).ToString();
7475
default:
75-
Debug.Fail("Invalid primitive type");
76-
return null;
76+
throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
7777
}
7878
}
7979

@@ -133,12 +133,12 @@ private static string ValueToHexString(object value)
133133
}
134134
}
135135

136-
internal static string GetEnumName(RuntimeType enumType, ulong ulValue)
136+
internal static string? GetEnumName(RuntimeType enumType, ulong ulValue)
137137
{
138138
return GetEnumName(GetEnumInfo(enumType), ulValue);
139139
}
140140

141-
private static string GetEnumName(EnumInfo enumInfo, ulong ulValue)
141+
private static string? GetEnumName(EnumInfo enumInfo, ulong ulValue)
142142
{
143143
int index = Array.BinarySearch(enumInfo.Values, ulValue);
144144
if (index >= 0)
@@ -149,7 +149,7 @@ private static string GetEnumName(EnumInfo enumInfo, ulong ulValue)
149149
return null; // return null so the caller knows to .ToString() the input
150150
}
151151

152-
private static string InternalFormat(RuntimeType enumType, ulong value)
152+
private static string? InternalFormat(RuntimeType enumType, ulong value)
153153
{
154154
EnumInfo enumInfo = GetEnumInfo(enumType);
155155

@@ -163,12 +163,12 @@ private static string InternalFormat(RuntimeType enumType, ulong value)
163163
}
164164
}
165165

166-
private static string InternalFlagsFormat(RuntimeType enumType, ulong result)
166+
private static string? InternalFlagsFormat(RuntimeType enumType, ulong result)
167167
{
168168
return InternalFlagsFormat(enumType, GetEnumInfo(enumType), result);
169169
}
170170

171-
private static string InternalFlagsFormat(RuntimeType enumType, EnumInfo enumInfo, ulong resultValue)
171+
private static string? InternalFlagsFormat(RuntimeType enumType, EnumInfo enumInfo, ulong resultValue)
172172
{
173173
Debug.Assert(enumType != null);
174174

@@ -322,9 +322,9 @@ public static object Parse(Type enumType, string value) =>
322322

323323
public static object Parse(Type enumType, string value, bool ignoreCase)
324324
{
325-
bool success = TryParse(enumType, value, ignoreCase, throwOnFailure: true, out object result);
325+
bool success = TryParse(enumType, value, ignoreCase, throwOnFailure: true, out object? result);
326326
Debug.Assert(success);
327-
return result;
327+
return result!;
328328
}
329329

330330
public static TEnum Parse<TEnum>(string value) where TEnum : struct =>
@@ -337,13 +337,13 @@ public static TEnum Parse<TEnum>(string value, bool ignoreCase) where TEnum : st
337337
return result;
338338
}
339339

340-
public static bool TryParse(Type enumType, string value, out object result) =>
340+
public static bool TryParse(Type enumType, string? value, out object? result) =>
341341
TryParse(enumType, value, ignoreCase: false, out result);
342342

343-
public static bool TryParse(Type enumType, string value, bool ignoreCase, out object result) =>
343+
public static bool TryParse(Type enumType, string? value, bool ignoreCase, out object? result) =>
344344
TryParse(enumType, value, ignoreCase, throwOnFailure: false, out result);
345345

346-
private static bool TryParse(Type enumType, string value, bool ignoreCase, bool throwOnFailure, out object result)
346+
private static bool TryParse(Type enumType, string? value, bool ignoreCase, bool throwOnFailure, out object? result)
347347
{
348348
// Validation on the enum type itself. Failures here are considered non-parsing failures
349349
// and thus always throw rather than returning false.
@@ -413,13 +413,13 @@ private static bool TryParse(Type enumType, string value, bool ignoreCase, bool
413413
}
414414
}
415415

416-
public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct =>
416+
public static bool TryParse<TEnum>(string? value, out TEnum result) where TEnum : struct =>
417417
TryParse<TEnum>(value, ignoreCase: false, out result);
418418

419-
public static bool TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) where TEnum : struct =>
419+
public static bool TryParse<TEnum>(string? value, bool ignoreCase, out TEnum result) where TEnum : struct =>
420420
TryParse<TEnum>(value, ignoreCase, throwOnFailure: false, out result);
421421

422-
private static bool TryParse<TEnum>(string value, bool ignoreCase, bool throwOnFailure, out TEnum result) where TEnum : struct
422+
private static bool TryParse<TEnum>(string? value, bool ignoreCase, bool throwOnFailure, out TEnum result) where TEnum : struct
423423
{
424424
// Validation on the enum type itself. Failures here are considered non-parsing failures
425425
// and thus always throw rather than returning false.
@@ -493,15 +493,15 @@ private static bool TryParse<TEnum>(string value, bool ignoreCase, bool throwOnF
493493
return parsed;
494494

495495
default:
496-
parsed = TryParseRareEnum(rt, value, valueSpan, ignoreCase, throwOnFailure, out object objectResult);
496+
parsed = TryParseRareEnum(rt, value, valueSpan, ignoreCase, throwOnFailure, out object? objectResult);
497497
result = parsed ? (TEnum)objectResult : default;
498498
return parsed;
499499
}
500500
}
501501

502502
/// <summary>Tries to parse the value of an enum with known underlying types that fit in an Int32 (Int32, Int16, and SByte).</summary>
503503
private static bool TryParseInt32Enum(
504-
RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, int minInclusive, int maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out int result)
504+
RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, int minInclusive, int maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out int result)
505505
{
506506
Debug.Assert(
507507
enumType.GetEnumUnderlyingType() == typeof(sbyte) ||
@@ -542,7 +542,7 @@ private static bool TryParseInt32Enum(
542542
}
543543

544544
/// <summary>Tries to parse the value of an enum with known underlying types that fit in a UInt32 (UInt32, UInt16, and Byte).</summary>
545-
private static bool TryParseUInt32Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, uint maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out uint result)
545+
private static bool TryParseUInt32Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, uint maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out uint result)
546546
{
547547
Debug.Assert(
548548
enumType.GetEnumUnderlyingType() == typeof(byte) ||
@@ -583,7 +583,7 @@ private static bool TryParseUInt32Enum(RuntimeType enumType, string originalValu
583583
}
584584

585585
/// <summary>Tries to parse the value of an enum with Int64 as the underlying type.</summary>
586-
private static bool TryParseInt64Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out long result)
586+
private static bool TryParseInt64Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out long result)
587587
{
588588
Debug.Assert(enumType.GetEnumUnderlyingType() == typeof(long));
589589

@@ -615,7 +615,7 @@ private static bool TryParseInt64Enum(RuntimeType enumType, string originalValue
615615
}
616616

617617
/// <summary>Tries to parse the value of an enum with UInt64 as the underlying type.</summary>
618-
private static bool TryParseUInt64Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result)
618+
private static bool TryParseUInt64Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result)
619619
{
620620
Debug.Assert(enumType.GetEnumUnderlyingType() == typeof(ulong));
621621

@@ -646,7 +646,7 @@ private static bool TryParseUInt64Enum(RuntimeType enumType, string originalValu
646646
}
647647

648648
/// <summary>Tries to parse the value of an enum with an underlying type that can't be expressed in C# (e.g. char, bool, double, etc.)</summary>
649-
private static bool TryParseRareEnum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out object result)
649+
private static bool TryParseRareEnum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out object? result)
650650
{
651651
Debug.Assert(
652652
enumType.GetEnumUnderlyingType() != typeof(sbyte) &&
@@ -693,7 +693,7 @@ private static bool TryParseRareEnum(RuntimeType enumType, string originalValueS
693693
return false;
694694
}
695695

696-
private static bool TryParseByName(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result)
696+
private static bool TryParseByName(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result)
697697
{
698698
// Find the field. Let's assume that these are always static classes because the class is an enum.
699699
EnumInfo enumInfo = GetEnumInfo(enumType);
@@ -862,19 +862,19 @@ public static string Format(Type enumType, object value, string format)
862862
{
863863
case 'G':
864864
case 'g':
865-
return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString();
865+
return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString()!;
866866

867867
case 'D':
868868
case 'd':
869-
return value.ToString();
869+
return value.ToString()!;
870870

871871
case 'X':
872872
case 'x':
873873
return ValueToHexString(value);
874874

875875
case 'F':
876876
case 'f':
877-
return InternalFlagsFormat(rtType, ToUInt64(value)) ?? value.ToString();
877+
return InternalFlagsFormat(rtType, ToUInt64(value)) ?? value.ToString()!;
878878
}
879879
}
880880

@@ -917,8 +917,7 @@ internal object GetValue()
917917
case CorElementType.ELEMENT_TYPE_U:
918918
return Unsafe.As<byte, UIntPtr>(ref data);
919919
default:
920-
Debug.Fail("Invalid primitive type");
921-
return null;
920+
throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
922921
}
923922
}
924923

@@ -953,8 +952,7 @@ private ulong ToUInt64()
953952
case CorElementType.ELEMENT_TYPE_U:
954953
return (ulong)Unsafe.As<byte, UIntPtr>(ref data);
955954
default:
956-
Debug.Fail("Invalid primitive type");
957-
return 0;
955+
throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
958956
}
959957
}
960958

@@ -999,8 +997,7 @@ public override int GetHashCode()
999997
case CorElementType.ELEMENT_TYPE_U:
1000998
return Unsafe.As<byte, UIntPtr>(ref data).GetHashCode();
1001999
default:
1002-
Debug.Fail("Invalid primitive type");
1003-
return 0;
1000+
throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
10041001
}
10051002
}
10061003

@@ -1019,14 +1016,14 @@ public override string ToString()
10191016

10201017
#region IFormattable
10211018
[Obsolete("The provider argument is not used. Please use ToString(String).")]
1022-
public string ToString(string format, IFormatProvider provider)
1019+
public string ToString(string? format, IFormatProvider? provider)
10231020
{
10241021
return ToString(format);
10251022
}
10261023
#endregion
10271024

10281025
#region Public Methods
1029-
public string ToString(string format)
1026+
public string ToString(string? format)
10301027
{
10311028
if (string.IsNullOrEmpty(format))
10321029
{
@@ -1059,7 +1056,7 @@ public string ToString(string format)
10591056
}
10601057

10611058
[Obsolete("The provider argument is not used. Please use ToString().")]
1062-
public string ToString(IFormatProvider provider)
1059+
public string ToString(IFormatProvider? provider)
10631060
{
10641061
return ToString();
10651062
}
@@ -1096,77 +1093,77 @@ public TypeCode GetTypeCode()
10961093
}
10971094
}
10981095

1099-
bool IConvertible.ToBoolean(IFormatProvider provider)
1096+
bool IConvertible.ToBoolean(IFormatProvider? provider)
11001097
{
11011098
return Convert.ToBoolean(GetValue(), CultureInfo.CurrentCulture);
11021099
}
11031100

1104-
char IConvertible.ToChar(IFormatProvider provider)
1101+
char IConvertible.ToChar(IFormatProvider? provider)
11051102
{
11061103
return Convert.ToChar(GetValue(), CultureInfo.CurrentCulture);
11071104
}
11081105

1109-
sbyte IConvertible.ToSByte(IFormatProvider provider)
1106+
sbyte IConvertible.ToSByte(IFormatProvider? provider)
11101107
{
11111108
return Convert.ToSByte(GetValue(), CultureInfo.CurrentCulture);
11121109
}
11131110

1114-
byte IConvertible.ToByte(IFormatProvider provider)
1111+
byte IConvertible.ToByte(IFormatProvider? provider)
11151112
{
11161113
return Convert.ToByte(GetValue(), CultureInfo.CurrentCulture);
11171114
}
11181115

1119-
short IConvertible.ToInt16(IFormatProvider provider)
1116+
short IConvertible.ToInt16(IFormatProvider? provider)
11201117
{
11211118
return Convert.ToInt16(GetValue(), CultureInfo.CurrentCulture);
11221119
}
11231120

1124-
ushort IConvertible.ToUInt16(IFormatProvider provider)
1121+
ushort IConvertible.ToUInt16(IFormatProvider? provider)
11251122
{
11261123
return Convert.ToUInt16(GetValue(), CultureInfo.CurrentCulture);
11271124
}
11281125

1129-
int IConvertible.ToInt32(IFormatProvider provider)
1126+
int IConvertible.ToInt32(IFormatProvider? provider)
11301127
{
11311128
return Convert.ToInt32(GetValue(), CultureInfo.CurrentCulture);
11321129
}
11331130

1134-
uint IConvertible.ToUInt32(IFormatProvider provider)
1131+
uint IConvertible.ToUInt32(IFormatProvider? provider)
11351132
{
11361133
return Convert.ToUInt32(GetValue(), CultureInfo.CurrentCulture);
11371134
}
11381135

1139-
long IConvertible.ToInt64(IFormatProvider provider)
1136+
long IConvertible.ToInt64(IFormatProvider? provider)
11401137
{
11411138
return Convert.ToInt64(GetValue(), CultureInfo.CurrentCulture);
11421139
}
11431140

1144-
ulong IConvertible.ToUInt64(IFormatProvider provider)
1141+
ulong IConvertible.ToUInt64(IFormatProvider? provider)
11451142
{
11461143
return Convert.ToUInt64(GetValue(), CultureInfo.CurrentCulture);
11471144
}
11481145

1149-
float IConvertible.ToSingle(IFormatProvider provider)
1146+
float IConvertible.ToSingle(IFormatProvider? provider)
11501147
{
11511148
return Convert.ToSingle(GetValue(), CultureInfo.CurrentCulture);
11521149
}
11531150

1154-
double IConvertible.ToDouble(IFormatProvider provider)
1151+
double IConvertible.ToDouble(IFormatProvider? provider)
11551152
{
11561153
return Convert.ToDouble(GetValue(), CultureInfo.CurrentCulture);
11571154
}
11581155

1159-
decimal IConvertible.ToDecimal(IFormatProvider provider)
1156+
decimal IConvertible.ToDecimal(IFormatProvider? provider)
11601157
{
11611158
return Convert.ToDecimal(GetValue(), CultureInfo.CurrentCulture);
11621159
}
11631160

1164-
DateTime IConvertible.ToDateTime(IFormatProvider provider)
1161+
DateTime IConvertible.ToDateTime(IFormatProvider? provider)
11651162
{
11661163
throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Enum", "DateTime"));
11671164
}
11681165

1169-
object IConvertible.ToType(Type type, IFormatProvider provider)
1166+
object IConvertible.ToType(Type type, IFormatProvider? provider)
11701167
{
11711168
return Convert.DefaultToType((IConvertible)this, type, provider);
11721169
}

0 commit comments

Comments
 (0)