不安全的通用:T[] 和 T[] - C# 7.3+
Generic for unsafe: T[,] and T[,,] - C# 7.3+
我 运行 c# 7.3 所以请不要评论 'this will never work'
我有 2 个 类 具有通用接口:
Image2D 和 Image3D 以及通用接口图像
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; }
....
}
我现在想做什么:无论输入是 I3D 还是 I2D 类型,我都需要对数据数组进行不安全访问...
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 ...
}
这当然行不通:'Can not convert initializer type S to type T*' 这很有道理……但是我怎样才能得到数组的数据类型呢?有没有更好的办法解决这个问题?
我想知道这里的诀窍是不是 S Data { get; }
,有(作为 Data
,或作为不同的 属性):ref T Data {get;}
.
假设你有底层数组,你应该能够使用所有的零来获得这个引用;所以对于 2D 情况:
public ref T Data => ref arr[0, 0];
T[,] arr;
对于 3D 案例:
public ref T Data => ref arr[0, 0, 0];
T[,,] arr;
现在您可以使用:
ref var data = ref image.Data;
fixed (T* pData = &data)
{
}
虽然坦率地说我怀疑你也可以做你需要的一切 没有 unsafe
- 特别是通过 MemoryMarshal
和 Unsafe
(nuget)
我 运行 c# 7.3 所以请不要评论 'this will never work'
我有 2 个 类 具有通用接口: Image2D 和 Image3D 以及通用接口图像
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; }
....
}
我现在想做什么:无论输入是 I3D 还是 I2D 类型,我都需要对数据数组进行不安全访问...
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 ...
}
这当然行不通:'Can not convert initializer type S to type T*' 这很有道理……但是我怎样才能得到数组的数据类型呢?有没有更好的办法解决这个问题?
我想知道这里的诀窍是不是 S Data { get; }
,有(作为 Data
,或作为不同的 属性):ref T Data {get;}
.
假设你有底层数组,你应该能够使用所有的零来获得这个引用;所以对于 2D 情况:
public ref T Data => ref arr[0, 0];
T[,] arr;
对于 3D 案例:
public ref T Data => ref arr[0, 0, 0];
T[,,] arr;
现在您可以使用:
ref var data = ref image.Data;
fixed (T* pData = &data)
{
}
虽然坦率地说我怀疑你也可以做你需要的一切 没有 unsafe
- 特别是通过 MemoryMarshal
和 Unsafe
(nuget)