Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 37 additions & 48 deletions src/Microsoft.Extensions.Primitives/StringValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Primitives
public readonly struct StringValues : IList<string>, IReadOnlyList<string>, IEquatable<StringValues>, IEquatable<string>, IEquatable<string[]>
{
private static readonly string[] EmptyArray = new string[0];
public static readonly StringValues Empty = new StringValues(EmptyArray);
public static readonly StringValues Empty = default;

private readonly string _value;
private readonly string[] _values;
Expand All @@ -27,8 +27,23 @@ public StringValues(string value)

public StringValues(string[] values)
{
_value = null;
_values = values;
if (values == null || values.Length == 0)
{
// Set null and empty arrays to null
_value = null; // Both null is required for
_values = null; // IsNull property to work correctly
}
else if (values.Length == 1)
{
// Set single item arrays to the string value
_values = null;
_value = values[0];
}
else
{
_value = null;
_values = values;
}
}

public static implicit operator StringValues(string value)
Expand All @@ -48,11 +63,13 @@ public static implicit operator string (StringValues values)

public static implicit operator string[] (StringValues value)
{
return value.GetArrayValue();
return value.ToArray();
}

public int Count => _value != null ? 1 : (_values?.Length ?? 0);

public bool IsNull => _value == null && _values == null;

bool ICollection<string>.IsReadOnly
{
get { return true; }
Expand Down Expand Up @@ -85,33 +102,9 @@ public override string ToString()
return GetStringValue() ?? string.Empty;
}

private string GetStringValue()
{
if (_values == null)
{
return _value;
}
switch (_values.Length)
{
case 0: return null;
case 1: return _values[0];
default: return string.Join(",", _values);
}
}

public string[] ToArray()
{
return GetArrayValue() ?? EmptyArray;
}
private string GetStringValue() => (_values == null) ? _value : string.Join(",", _values);

private string[] GetArrayValue()
{
if (_value != null)
{
return new[] { _value };
}
return _values;
}
public string[] ToArray() => (_values != null) ? new[] { _value } : (_values ?? EmptyArray);

int IList<string>.IndexOf(string item)
{
Expand Down Expand Up @@ -225,29 +218,25 @@ public static bool IsNullOrEmpty(StringValues value)
{
return string.IsNullOrEmpty(value._value);
}
switch (value._values.Length)
{
case 0: return true;
case 1: return string.IsNullOrEmpty(value._values[0]);
default: return false;
}

return false;
}

public static StringValues Concat(StringValues values1, StringValues values2)
{
var count1 = values1.Count;
var count2 = values2.Count;

if (count1 == 0)
if (values1.IsNull)
{
return values2;
}

if (count2 == 0)
if (values2.IsNull)
{
return values1;
}

var count1 = values1.Count;
var count2 = values2.Count;
var combined = new string[count1 + count2];
values1.CopyTo(combined, 0);
values2.CopyTo(combined, count1);
Expand All @@ -261,12 +250,12 @@ public static StringValues Concat(in StringValues values, string value)
return values;
}

var count = values.Count;
if (count == 0)
if (values.IsNull)
{
return new StringValues(value);
}

var count = values.Count;
var combined = new string[count + 1];
values.CopyTo(combined, 0);
combined[count] = value;
Expand All @@ -280,12 +269,12 @@ public static StringValues Concat(string value, in StringValues values)
return values;
}

var count = values.Count;
if (count == 0)
if (values.IsNull)
{
return new StringValues(value);
}

var count = values.Count;
var combined = new string[count + 1];
combined[0] = value;
values.CopyTo(combined, 1);
Expand Down Expand Up @@ -420,12 +409,12 @@ public override bool Equals(object obj)
{
if (obj == null)
{
return Equals(this, StringValues.Empty);
return this.IsNull;
}

if (obj is string)
if (obj is string str)
{
return Equals(this, (string)obj);
return this._value == str;
}

if (obj is string[])
Expand Down Expand Up @@ -514,4 +503,4 @@ public void Dispose()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public void IsReadOnly_True(StringValues stringValues)
[MemberData(nameof(DefaultOrNullStringValues))]
public void DefaultOrNull_ExpectedValues(StringValues stringValues)
{
Assert.Null((string[])stringValues);
Assert.Empty((string[])stringValues);
}

[Theory]
Expand Down Expand Up @@ -165,7 +165,7 @@ public void ImplicitStringConverter_Works()
StringValues stringValues = nullString;
Assert.Empty(stringValues);
Assert.Null((string)stringValues);
Assert.Null((string[])stringValues);
Assert.Empty((string[])stringValues);

string aString = "abc";
stringValues = aString;
Expand All @@ -183,7 +183,7 @@ public void ImplicitStringArrayConverter_Works()
StringValues stringValues = nullStringArray;
Assert.Empty(stringValues);
Assert.Null((string)stringValues);
Assert.Null((string[])stringValues);
Assert.Empty((string[])stringValues);

string aString = "abc";
string[] aStringArray = new[] { aString };
Expand Down