Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit cd48d86

Browse files
ahsonkhanjkotas
authored andcommitted
Changing Span to return default on null instead of throwing.
1 parent c98a153 commit cd48d86

File tree

15 files changed

+141
-66
lines changed

15 files changed

+141
-66
lines changed

src/Common/src/CoreLib/System/ReadOnlySpan.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public int Length
2929
#if !FEATURE_PORTABLE_SPAN
3030
[NonVersionable]
3131
#endif // !FEATURE_PORTABLE_SPAN
32-
get
33-
{
34-
return _length;
35-
}
36-
}
32+
get
33+
{
34+
return _length;
35+
}
36+
}
3737

3838
/// <summary>
3939
/// Returns true if Length is 0.

src/Common/src/CoreLib/System/Span.NonGeneric.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,4 +549,4 @@ internal static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSize
549549
}
550550
}
551551
}
552-
}
552+
}

src/Common/src/CoreLib/System/Span.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public int Length
2929
#if !FEATURE_PORTABLE_SPAN
3030
[NonVersionable]
3131
#endif // !FEATURE_PORTABLE_SPAN
32-
get
33-
{
34-
return _length;
35-
}
36-
}
32+
get
33+
{
34+
return _length;
35+
}
36+
}
3737

3838
/// <summary>
3939
/// Returns true if Length is 0.

src/System.Memory/System.Memory.sln

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Microsoft Visual Studio Solution File, Format Version 12.00
2-
# Visual Studio 14
3-
VisualStudioVersion = 14.0.25420.1
2+
# Visual Studio 15
3+
VisualStudioVersion = 15.0.27331.1
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Memory.Tests", "tests\System.Memory.Tests.csproj", "{15DB0DCC-68B4-4CFB-8BD2-F26BCCAF5A3F}"
66
ProjectSection(ProjectDependencies) = postProject
@@ -25,6 +25,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E89
2525
EndProject
2626
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}"
2727
EndProject
28+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3F794AE4-319F-4498-A9DA-C49A4EB11D9E}"
29+
ProjectSection(SolutionItems) = preProject
30+
..\Common\src\CoreLib\System\ReadOnlySpan.Fast.cs = ..\Common\src\CoreLib\System\ReadOnlySpan.Fast.cs
31+
..\Common\src\CoreLib\System\Span.Fast.cs = ..\Common\src\CoreLib\System\Span.Fast.cs
32+
..\Common\src\CoreLib\System\Span.NonGeneric.cs = ..\Common\src\CoreLib\System\Span.NonGeneric.cs
33+
EndProjectSection
34+
EndProject
2835
Global
2936
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3037
Debug|Any CPU = Debug|Any CPU
@@ -57,4 +64,7 @@ Global
5764
{4BBC8F69-D03E-4432-AA8A-D458FA5B235A} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
5865
{E883935B-D8FD-4FC9-A189-9D9E7F7EF550} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
5966
EndGlobalSection
67+
GlobalSection(ExtensibilityGlobals) = postSolution
68+
SolutionGuid = {D1974D36-E7EF-4503-B474-D92F2D79ABE5}
69+
EndGlobalSection
6070
EndGlobal

src/System.Memory/src/System/MemoryExtensions.Fast.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static partial class MemoryExtensions
4343
/// Creates a new readonly span over the portion of the target string.
4444
/// </summary>
4545
/// <param name="text">The target string.</param>
46-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception>
46+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
4747
public static ReadOnlySpan<char> AsReadOnlySpan(this string text) => Span.AsReadOnlySpan(text);
4848

4949
/// <summary>
@@ -63,21 +63,21 @@ public static partial class MemoryExtensions
6363
/// <param name="text">The target string.</param>
6464
/// <param name="start">The index at which to begin this slice.</param>
6565
/// <param name="length">The desired length for the slice (exclusive).</param>
66-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception>
66+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
6767
/// <exception cref="System.ArgumentOutOfRangeException">
6868
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
6969
/// </exception>
7070
public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start, int length) => Span.AsReadOnlySpan(text, start, length);
7171

7272
/// <summary>Creates a new <see cref="ReadOnlyMemory{T}"/> over the portion of the target string.</summary>
7373
/// <param name="text">The target string.</param>
74-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
74+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
7575
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text) => Span.AsReadOnlyMemory(text);
7676

7777
/// <summary>Creates a new <see cref="ReadOnlyMemory{T}"/> over the portion of the target string.</summary>
7878
/// <param name="text">The target string.</param>
7979
/// <param name="start">The index at which to begin this slice.</param>
80-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
80+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
8181
/// <exception cref="System.ArgumentOutOfRangeException">
8282
/// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;text.Length).
8383
/// </exception>
@@ -87,7 +87,7 @@ public static partial class MemoryExtensions
8787
/// <param name="text">The target string.</param>
8888
/// <param name="start">The index at which to begin this slice.</param>
8989
/// <param name="length">The desired length for the slice (exclusive).</param>
90-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
90+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
9191
/// <exception cref="System.ArgumentOutOfRangeException">
9292
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
9393
/// </exception>

src/System.Memory/src/System/MemoryExtensions.Portable.cs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> source)
6060
/// Creates a new readonly span over the portion of the target string.
6161
/// </summary>
6262
/// <param name="text">The target string.</param>
63-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception>
63+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
6464
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6565
public static ReadOnlySpan<char> AsReadOnlySpan(this string text)
6666
{
6767
if (text == null)
68-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
68+
return default;
6969

7070
return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment, text.Length);
7171
}
@@ -75,15 +75,19 @@ public static ReadOnlySpan<char> AsReadOnlySpan(this string text)
7575
/// </summary>
7676
/// <param name="text">The target string.</param>
7777
/// <param name="start">The index at which to begin this slice.</param>
78-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception>
78+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
7979
/// <exception cref="System.ArgumentOutOfRangeException">
8080
/// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;text.Length).
8181
/// </exception>
8282
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8383
public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start)
8484
{
8585
if (text == null)
86-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
86+
{
87+
if (start != 0)
88+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
89+
return default;
90+
}
8791
if ((uint)start > (uint)text.Length)
8892
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
8993

@@ -96,15 +100,19 @@ public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start)
96100
/// <param name="text">The target string.</param>
97101
/// <param name="start">The index at which to begin this slice.</param>
98102
/// <param name="length">The desired length for the slice (exclusive).</param>
99-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception>
103+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
100104
/// <exception cref="System.ArgumentOutOfRangeException">
101105
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
102106
/// </exception>
103107
[MethodImpl(MethodImplOptions.AggressiveInlining)]
104108
public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start, int length)
105109
{
106110
if (text == null)
107-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
111+
{
112+
if (start != 0 || length != 0)
113+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
114+
return default;
115+
}
108116
if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
109117
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
110118

@@ -113,26 +121,30 @@ public static ReadOnlySpan<char> AsReadOnlySpan(this string text, int start, int
113121

114122
/// <summary>Creates a new <see cref="ReadOnlyMemory{T}"/> over the portion of the target string.</summary>
115123
/// <param name="text">The target string.</param>
116-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
124+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
117125
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text)
118126
{
119127
if (text == null)
120-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
128+
return default;
121129

122130
return new ReadOnlyMemory<char>(text, 0, text.Length);
123131
}
124132

125133
/// <summary>Creates a new <see cref="ReadOnlyMemory{T}"/> over the portion of the target string.</summary>
126134
/// <param name="text">The target string.</param>
127135
/// <param name="start">The index at which to begin this slice.</param>
128-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
136+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
129137
/// <exception cref="System.ArgumentOutOfRangeException">
130138
/// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;text.Length).
131139
/// </exception>
132140
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text, int start)
133141
{
134142
if (text == null)
135-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
143+
{
144+
if (start != 0)
145+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
146+
return default;
147+
}
136148
if ((uint)start > (uint)text.Length)
137149
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
138150

@@ -143,14 +155,18 @@ public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text, int start)
143155
/// <param name="text">The target string.</param>
144156
/// <param name="start">The index at which to begin this slice.</param>
145157
/// <param name="length">The desired length for the slice (exclusive).</param>
146-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null reference (Nothing in Visual Basic).</exception>
158+
/// <remarks>Returns default when <paramref name="text"/> is null.</remarks>
147159
/// <exception cref="System.ArgumentOutOfRangeException">
148160
/// Thrown when the specified <paramref name="start"/> index or <paramref name="length"/> is not in range.
149161
/// </exception>
150162
public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text, int start, int length)
151163
{
152164
if (text == null)
153-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
165+
{
166+
if (start != 0 || length != 0)
167+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
168+
return default;
169+
}
154170
if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
155171
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
156172

src/System.Memory/src/System/ReadOnlySpan.Portable.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ public readonly ref partial struct ReadOnlySpan<T>
2323
/// Creates a new read-only span over the entirety of the target array.
2424
/// </summary>
2525
/// <param name="array">The target array.</param>
26-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
27-
/// reference (Nothing in Visual Basic).</exception>
26+
/// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
2827
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
2928
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3029
public ReadOnlySpan(T[] array)
3130
{
3231
if (array == null)
33-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
32+
{
33+
this = default;
34+
return; // returns default
35+
}
3436

3537
_length = array.Length;
3638
_pinnable = Unsafe.As<Pinnable<T>>(array);
@@ -44,8 +46,7 @@ public ReadOnlySpan(T[] array)
4446
/// <param name="array">The target array.</param>
4547
/// <param name="start">The index at which to begin the read-only span.</param>
4648
/// <param name="length">The number of items in the read-only span.</param>
47-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
48-
/// reference (Nothing in Visual Basic).</exception>
49+
/// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
4950
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
5051
/// <exception cref="System.ArgumentOutOfRangeException">
5152
/// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
@@ -54,7 +55,12 @@ public ReadOnlySpan(T[] array)
5455
public ReadOnlySpan(T[] array, int start, int length)
5556
{
5657
if (array == null)
57-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
58+
{
59+
if (start != 0 || length != 0)
60+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
61+
this = default;
62+
return; // returns default
63+
}
5864
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
5965
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
6066

src/System.Memory/src/System/Span.Portable.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ public readonly ref partial struct Span<T>
2323
/// Creates a new span over the entirety of the target array.
2424
/// </summary>
2525
/// <param name="array">The target array.</param>
26-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
27-
/// reference (Nothing in Visual Basic).</exception>
26+
/// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
2827
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
2928
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3029
public Span(T[] array)
3130
{
3231
if (array == null)
33-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
32+
{
33+
this = default;
34+
return; // returns default
35+
}
3436
if (default(T) == null && array.GetType() != typeof(T[]))
3537
ThrowHelper.ThrowArrayTypeMismatchException();
3638

@@ -46,8 +48,7 @@ public Span(T[] array)
4648
/// <param name="array">The target array.</param>
4749
/// <param name="start">The index at which to begin the span.</param>
4850
/// <param name="length">The number of items in the span.</param>
49-
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
50-
/// reference (Nothing in Visual Basic).</exception>
51+
/// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
5152
/// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
5253
/// <exception cref="System.ArgumentOutOfRangeException">
5354
/// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
@@ -56,7 +57,12 @@ public Span(T[] array)
5657
public Span(T[] array, int start, int length)
5758
{
5859
if (array == null)
59-
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
60+
{
61+
if (start != 0 || length != 0)
62+
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
63+
this = default;
64+
return; // returns default
65+
}
6066
if (default(T) == null && array.GetType() != typeof(T[]))
6167
ThrowHelper.ThrowArrayTypeMismatchException();
6268
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))

src/System.Memory/src/System/ThrowHelper.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,16 @@ public static bool TryParseThrowFormatException<T>(out T value, out int bytesCon
106106
}
107107
}
108108

109+
//
110+
// The convention for this enum is using the argument name as the enum name
111+
//
109112
internal enum ExceptionArgument
110113
{
111114
array,
112115
length,
113116
start,
114-
text,
115-
obj,
116-
ownedMemory,
117117
minimumBufferSize,
118118
byteOffset,
119-
pointer,
120119
comparable,
121120
comparer
122121
}

src/System.Memory/tests/Memory/CtorArray.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ public static void CtorArrayZeroLength()
7171
[Fact]
7272
public static void CtorArrayNullArray()
7373
{
74-
Assert.Throws<ArgumentNullException>(() => new Memory<int>(null));
75-
Assert.Throws<ArgumentNullException>(() => new Memory<int>(null, 0, 0));
74+
var memory = new Memory<int>(null);
75+
memory.Validate();
76+
Assert.Equal(default, memory);
77+
78+
memory = new Memory<int>(null, 0, 0);
79+
memory.Validate();
80+
Assert.Equal(default, memory);
7681
}
7782

7883
[Fact]

0 commit comments

Comments
 (0)