I run c# 7.3 so please no comments like 'this will never work'
I have 2 Classes with a common interface: Image2D and Image3D and the Common Interface Image
public interface IImage<T, S> where T : unmanaged {
long Length { get; }
S Data { get; }
T GetMaxTypeValue();
T GetMinTypeValue();
}
public abstract class I2D<T> : IImage<T, T[,]> where T : unmanaged {
public int LengthX { get; }
public int LengthY { get; }
public T[,] Data { get; }
...
}
public abstract class I3D<T> : IImage<T, T[,,]> where T : unmanaged {
public int LengthX { get; }
public int LengthY { get; }
public int LengthZ { get; }
public T[,,] Data { get; }
....
}
What I am trying to do now: No matter if the input is of type I3D or I2D i need unsafe access on the Data array...
public static unsafe T Smth<T, S>(IImage<T, S> image) where T : unmanaged where S : unmanaged {
var data = image.Data;
fixed (T* pData = data) {
do someting
}
return ...
}
This, of course, does not work: 'Can not convert initializer type S to type T*' which makes sense... But how Can I get the datatype of the arrays? Is there a better way to solve this problem?
I wonder if the trick here is instead of S Data { get; }
, to have (either as Data
, or as a different property): ref T Data {get;}
.
Assuming you have underlying arrays, you should be able to use all the zeros to get this reference; so for the 2D case:
public ref T Data => ref arr[0, 0];
T[,] arr;
and for the 3D case:
public ref T Data => ref arr[0, 0, 0];
T[,,] arr;
Now you can use:
ref var data = ref image.Data;
fixed (T* pData = &data)
{
}
Although frankly I suspect you can also do everything you need without unsafe
- especially via MemoryMarshal
and Unsafe
(nuget)