Skip to content
Merged
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
29 changes: 29 additions & 0 deletions Ramstack.Structures.Tests/Collections/ArrayViewExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Ramstack.Collections;

[TestFixture]
public class ArrayViewExtensionsTests
{
#if NET9_0_OR_GREATER

[Test]
public void List_AsView_Empty()
{
var list = new List<string>();
var view = list.AsView();

Assert.That(view.Length, Is.EqualTo(list.Count));
Assert.That(view, Is.EquivalentTo(list));
}

[Test]
public void List_AsView()
{
var list = new List<string> { "apple", "banana", "cherry", "kiwi", "elderberry" };
var view = list.AsView();

Assert.That(view.Length, Is.EqualTo(list.Count));
Assert.That(view, Is.EquivalentTo(list));
}

#endif
}
2 changes: 1 addition & 1 deletion Ramstack.Structures.Tests/Ramstack.Structures.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
Expand Down
48 changes: 48 additions & 0 deletions Ramstack.Structures/Collections/ArrayViewExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,52 @@ static int Impl(ReadOnlySpan<T> span, T value, IEqualityComparer<T>? comparer)
return -1;
}
}

#if NET9_0_OR_GREATER

/// <summary>
/// Returns an <see cref="ArrayView{T}"/> over the specified list.
/// Items should not be added or removed from the <see cref="List{T}"/>
/// while the <see cref="ArrayView{T}"/> is in use.
/// </summary>
/// <typeparam name="T">The type of the elements in the list.</typeparam>
/// <param name="list">The list to get the data view over.</param>
/// <returns>
/// A <see cref="ArrayView{T}"/> instance over the specified list.
/// </returns>
public static ArrayView<T> AsView<T>(this List<T>? list)
{
if (list is not null)
{
var count = list.Count;
var array = ListAccessor<T>.GetBuffer(list);

return new ArrayView<T>(array, 0, Math.Min(count, array.Length));
}

return ArrayView<T>.Empty;
}

#region Inner type: ListAccessor<T>

/// <summary>
/// Provides low-level access to the internal array buffer of a <see cref="List{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the elements in the list.</typeparam>
private static class ListAccessor<T>
{
/// <summary>
/// Retrieves a reference to the internal array buffer of the specified <see cref="List{T}"/>.
/// </summary>
/// <param name="list">The list whose internal buffer is to be accessed.</param>
/// <returns>
/// A reference to the internal array used by the list.
/// </returns>
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_items")]
public static extern ref T[] GetBuffer(List<T> list);
}

#endregion

#endif
}
2 changes: 1 addition & 1 deletion Ramstack.Structures/Ramstack.Structures.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
<Description>Provides various data structures and utilities.

Includes three primary types:
Expand Down