Skip to content

Commit eb620f6

Browse files
authored
Merge pull request #8 from rameel/list-asview
Add List<T> to ArrayView<T> extension for NET9.0+
2 parents 8953bf4 + d3a5c1c commit eb620f6

4 files changed

Lines changed: 79 additions & 2 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace Ramstack.Collections;
2+
3+
[TestFixture]
4+
public class ArrayViewExtensionsTests
5+
{
6+
#if NET9_0_OR_GREATER
7+
8+
[Test]
9+
public void List_AsView_Empty()
10+
{
11+
var list = new List<string>();
12+
var view = list.AsView();
13+
14+
Assert.That(view.Length, Is.EqualTo(list.Count));
15+
Assert.That(view, Is.EquivalentTo(list));
16+
}
17+
18+
[Test]
19+
public void List_AsView()
20+
{
21+
var list = new List<string> { "apple", "banana", "cherry", "kiwi", "elderberry" };
22+
var view = list.AsView();
23+
24+
Assert.That(view.Length, Is.EqualTo(list.Count));
25+
Assert.That(view, Is.EquivalentTo(list));
26+
}
27+
28+
#endif
29+
}

Ramstack.Structures.Tests/Ramstack.Structures.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
3+
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
44
<ImplicitUsings>enable</ImplicitUsings>
55
<Nullable>enable</Nullable>
66
<LangVersion>preview</LangVersion>

Ramstack.Structures/Collections/ArrayViewExtensions.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,52 @@ static int Impl(ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer)
133133
return -1;
134134
}
135135
}
136+
137+
#if NET9_0_OR_GREATER
138+
139+
/// <summary>
140+
/// Returns an <see cref="ArrayView{T}"/> over the specified list.
141+
/// Items should not be added or removed from the <see cref="List{T}"/>
142+
/// while the <see cref="ArrayView{T}"/> is in use.
143+
/// </summary>
144+
/// <typeparam name="T">The type of the elements in the list.</typeparam>
145+
/// <param name="list">The list to get the data view over.</param>
146+
/// <returns>
147+
/// A <see cref="ArrayView{T}"/> instance over the specified list.
148+
/// </returns>
149+
public static ArrayView<T> AsView<T>(this List<T>? list)
150+
{
151+
if (list is not null)
152+
{
153+
var count = list.Count;
154+
var array = ListAccessor<T>.GetBuffer(list);
155+
156+
return new ArrayView<T>(array, 0, Math.Min(count, array.Length));
157+
}
158+
159+
return ArrayView<T>.Empty;
160+
}
161+
162+
#region Inner type: ListAccessor<T>
163+
164+
/// <summary>
165+
/// Provides low-level access to the internal array buffer of a <see cref="List{T}"/>.
166+
/// </summary>
167+
/// <typeparam name="T">The type of the elements in the list.</typeparam>
168+
private static class ListAccessor<T>
169+
{
170+
/// <summary>
171+
/// Retrieves a reference to the internal array buffer of the specified <see cref="List{T}"/>.
172+
/// </summary>
173+
/// <param name="list">The list whose internal buffer is to be accessed.</param>
174+
/// <returns>
175+
/// A reference to the internal array used by the list.
176+
/// </returns>
177+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_items")]
178+
public static extern ref T[] GetBuffer(List<T> list);
179+
}
180+
181+
#endregion
182+
183+
#endif
136184
}

Ramstack.Structures/Ramstack.Structures.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
3+
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
44
<Description>Provides various data structures and utilities.
55

66
Includes three primary types:

0 commit comments

Comments
 (0)