using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
public interface IVector3<TVector, TValue> : IAdditionOperators<TVector, TVector, TVector>
where TValue : unmanaged, INumber<TValue>
where TVector : IVector3<TVector, TValue>, new ()
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Vector3Double : IVector3<Vector3Double, double>
public double X { get; init; }
public double Y { get; init; }
public double Z { get; init; }
public Vector3Double(double x, double y, double z) => (X, Y, Z) = (x, y, z);
public static Vector3Double operator +(Vector3Double left, Vector3Double right) => new Vector3Double() { X = left.X + right.X, Y = left.Y + right.Y, Z = left.Z + right.Z };
public static Vector3Double operator checked +(Vector3Double left, Vector3Double right) => new Vector3Double() { X = checked(left.X + right.X), Y = checked(left.Y + right.Y), Z = checked(left.Z + right.Z) };
public static class VectorExtensions
public static TVector Add<TVector, TValue>(this TVector left, TVector right)
where TValue : unmanaged, INumber<TValue>
where TVector : IVector3<TVector, TValue>, new ()
return new() { X = left.X + right.X, Y = left.Y + right.Y, Z = left.Z + right.Z };
public static TVector Scale<TVector, TValue>(this TVector left, TValue scale)
where TValue : unmanaged, INumber<TValue>
where TVector : IVector3<TVector, TValue>, new ()
return new() { X = scale*left.X, Y = scale*left.Y, Z = scale*left.Z };
public static void Main()
Console.WriteLine($"Marshal.SizeOf<Vector3Double>()={Marshal.SizeOf<Vector3Double>()}");
Console.WriteLine($"Marshal.SizeOf<Vector3Double>() failed with exception: {ex}");
var vec1 = new Vector3Double(1.1, 1.1, 1.1);
var vec2 = new Vector3Double(2.2, 2.2, 2.2);
Console.WriteLine($"vec1 + vec2 = {System.Text.Json.JsonSerializer.Serialize(vec3)}");
var v3 = vec1.Add<Vector3Double, double>(vec2);
var v32 = vec1.Add(vec2);
var scvec = vec1.Scale(2.2);