Reference<TValue>
Provides a reference to the memory location.
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Runtime
{
[StructLayout(LayoutKind.Auto)]
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public readonly struct Reference<[System.Runtime.CompilerServices.Nullable(2)] TValue>
{
private unsafe readonly void* accessor;
private readonly object owner;
public unsafe bool IsValid {
get {
if (accessor == null)
return owner is TValue[];
return true;
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private unsafe ref TValue RawValue {
get {
ref TValue result = ref Unsafe.NullRef<TValue>();
TValue[] array = owner as TValue[];
if (array != null)
ref result = ref Unsafe.Add<TValue>(ref MemoryMarshal.GetArrayDataReference<TValue>(array), (IntPtr)accessor);
else if (accessor != null) {
if (owner == null)
ref result = ref *(TValue*);
else if (owner == Sentinel.Instance) {
ref result = ref Unsafe.AsRef<TValue>(accessor);
} else {
IntPtr intPtr = (IntPtr)accessor;
ref result = ref *(TValue*);
}
}
return ref result;
}
}
public ref TValue Target {
get {
ref TValue rawValue = ref RawValue;
Intrinsics.ThrowIfNull<TValue>(ref rawValue);
return ref rawValue;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<TValue> Span {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
ref TValue rawValue = ref RawValue;
if (!Unsafe.IsNullRef<TValue>(ref rawValue))
return MemoryMarshal.CreateSpan<TValue>(ref rawValue, 1);
return Span<TValue>.Empty;
}
}
private unsafe Reference(object owner, IntPtr accessor)
{
this.owner = owner;
this.accessor = (void*)(long)accessor;
}
internal unsafe Reference(IntPtr accessor)
{
owner = null;
this.accessor = (void*)(long)accessor;
}
internal unsafe Reference(TValue[] array, [System.Runtime.CompilerServices.NativeInteger] IntPtr index)
{
owner = array;
accessor = (void*)(long)index;
}
internal unsafe Reference(void* pointer)
{
owner = Sentinel.Instance;
accessor = pointer;
}
internal static Reference<TValue> Create<TOwner>(TOwner owner, IntPtr accessor) where TOwner : class
{
return new Reference<TValue>((object)owner, accessor);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public override string ToString()
{
ref TValue rawValue = ref RawValue;
if (!Unsafe.IsNullRef<TValue>(ref rawValue)) {
ref TValue reference = ref rawValue;
TValue val = default(TValue);
if (val == null) {
val = reference;
ref reference = ref val;
if (val == null)
return null;
}
return reference.ToString();
}
return null;
}
}
}