Skip to content

Latest commit

 

History

History
141 lines (121 loc) · 3.1 KB

File metadata and controls

141 lines (121 loc) · 3.1 KB

Span and ReadOnlySpan

Specifying Span<T> and ReadOnlySpan<T> work the same as with the array T[].

using Shouldly;
using Pure.DI;

DI.Setup(nameof(Composition))
    .Bind<Point>('a').To(() => new Point(1, 1))
    .Bind<Point>('b').To(() => new Point(2, 2))
    .Bind<Point>('c').To(() => new Point(3, 3))
    .Bind<IPath>().To<Path>()

    // Composition root
    .Root<IPath>("Path");

var composition = new Composition();
var path = composition.Path;
path.PointCount.ShouldBe(3);

readonly struct Point(int x, int y)
{
    public int X { get; } = x;

    public int Y { get; } = y;
}

interface IPath
{
    int PointCount { get; }
}

class Path(ReadOnlySpan<Point> points) : IPath
{
    // The 'points' span is allocated on the stack, so it's very efficient.
    // However, we cannot store it in a field because it's a ref struct.
    // We can process it here in the constructor.
    public int PointCount { get; } = points.Length;
}
Running this code sample locally
dotnet --list-sdk
  • Create a net10.0 (or later) console application
dotnet new console -n Sample
dotnet add package Pure.DI
dotnet add package Shouldly
  • Copy the example code into the Program.cs file

You are ready to run the example 🚀

dotnet run

This scenario is even more efficient in the case of Span<T> or ReadOnlySpan<T> when T is a value type. In this case, there is no heap allocation, and the composition root IPath looks like this:

public IPath Path
{
  get
  {
    ReadOnlySpan<Point> points = stackalloc Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) };
    return new Path(points);
  }
}

The following partial class will be generated:

partial class Composition
{
  public IPath Path
  {
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    get
    {
      Point transientPoint445 = new Point(1, 1);
      Point transientPoint446 = new Point(2, 2);
      Point transientPoint447 = new Point(3, 3);
      return new Path(stackalloc Point[3] { transientPoint445, transientPoint446, transientPoint447 });
    }
  }
}

Class diagram:

---
 config:
  maxTextSize: 2147483647
  maxEdges: 2147483647
  class:
   hideEmptyMembersBox: true
---
classDiagram
	Path --|> IPath
	Composition ..> Path : IPath Path
	Path *--  ReadOnlySpanᐸPointᐳ : ReadOnlySpanᐸPointᐳ
	ReadOnlySpanᐸPointᐳ *--  Point : 'a'  Point
	ReadOnlySpanᐸPointᐳ *--  Point : 'b'  Point
	ReadOnlySpanᐸPointᐳ *--  Point : 'c'  Point
	namespace Pure.DI.UsageTests.BCL.SpanScenario {
		class Composition {
		<<partial>>
		+IPath Path
		}
		class IPath {
			<<interface>>
		}
		class Path {
				<<class>>
			+Path(ReadOnlySpanᐸPointᐳ points)
		}
		class Point {
				<<struct>>
		}
	}
	namespace System {
		class ReadOnlySpanᐸPointᐳ {
				<<struct>>
		}
	}
Loading