diff --git a/dotnet/build/common.props b/dotnet/build/common.props
index 78e1b3a..d994b78 100644
--- a/dotnet/build/common.props
+++ b/dotnet/build/common.props
@@ -14,7 +14,7 @@
1
- 112
+ 114
diff --git a/dotnet/src/Spreads.Native/UnsafeEx.cs b/dotnet/src/Spreads.Native/UnsafeEx.cs
index 0b33a07..e339ace 100644
--- a/dotnet/src/Spreads.Native/UnsafeEx.cs
+++ b/dotnet/src/Spreads.Native/UnsafeEx.cs
@@ -212,6 +212,18 @@ public static void SetAsObject(object obj, IntPtr offset, int index, object v
Unsafe.WriteUnaligned(ref Unsafe.As(ref GetRef(obj, offset, index)), value);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T ReadUnaligned(ref T source)
+ {
+ return Unsafe.ReadUnaligned(ref Unsafe.As(ref source));
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteUnaligned(ref T destination, T value)
+ {
+ Unsafe.WriteUnaligned(ref Unsafe.As(ref destination), value);
+ }
+
///
/// Get a native method pointer to method for type .
/// The pointer should be used with method.
diff --git a/dotnet/tests/Spreads.Native.Tests/VecTests.cs b/dotnet/tests/Spreads.Native.Tests/VecTests.cs
index 4956950..6d2990c 100644
--- a/dotnet/tests/Spreads.Native.Tests/VecTests.cs
+++ b/dotnet/tests/Spreads.Native.Tests/VecTests.cs
@@ -124,6 +124,30 @@ public void CouldUseVecSlice()
Assert.IsTrue(vecT.Span.SequenceEqual(vec.AsSpan()));
}
+ [Test]
+ public unsafe void ArrayAndPointerCtorsHaveSameBehavior()
+ {
+ var arr = new int[1000];
+ var pin = arr.AsMemory().Pin();
+
+ var vArr = new Vec(arr, 500, 500);
+ var vPtr = new Vec((byte*)pin.Pointer + 500 * 4, 500, typeof(int));
+
+ Assert.AreEqual(vArr.Length, vPtr.Length);
+
+ for (int i = 0; i < 1000; i++)
+ {
+ arr[i] = i;
+ }
+
+ for (int i = 0; i < 500; i++)
+ {
+ Assert.AreEqual(vArr.Get(i), vPtr.Get(i));
+ }
+
+ pin.Dispose();
+ }
+
[MethodImpl(MethodImplOptions.NoInlining
#if NETCOREAPP3_0
| MethodImplOptions.AggressiveOptimization