为什么不允许使用指向通用类型的指针? [英] Why is pointer to generic types not allowed?
问题描述
例如,作为重载的[]
setter-getter,
For example, as an overloaded []
setter-getter,
public T this[int i]
{
get
{
unsafe
{
T* p = (T*)hArr.ToPointer(); // hArr is a C++ object pointer(IntPtr)
return *(p + i);
}
}
set
{
unsafe
{
T* p = (T*)hArr.ToPointer();
*(p + i) = value;
}
}
}
并且编译器抱怨(强调)它不能使用...的地址"为托管类型T
.
and compiler complains(underlines) about it "cannot take address of ..." to a managed type T
.
我知道T
在运行时只会是float,double,int或byte,但是我不知道如何告诉编译器,因此它信任我.
I know T
will be only float,double,int or byte in runtime but I don't know how to tell this to compiler so it trusts me.
为什么我不能使用它,无论如何都是指针,如果不小心,我可能会溢出任何类型的数组.
Why can't I use it, all are pointers anyway, I can overflow any type of array if I'm not careful.
如何做到这一点(以类似的方式或另一种方式)而又不慢于:
How can I achieve this(with a similar way or another) without being much slower than:
public float this[int i]
{
get
{
unsafe
{
float* p = (float*)hArr.ToPointer();
return *(p + i);
}
}
set {
unsafe
{
float* p = (float*)hArr.ToPointer();
*(p + i) = value;
}
}
}
我不仅在这里关心性能,而且还关心代码的简单性. (对于所有T类型,只有一个代码)我想接口在这里无济于事.
I don't just care about performance here, but also code simplicity too. (one code for all T types) Interfaces can't help here I suppose.
推荐答案
C#将指针类型限制为
C# restricts pointer types to
-
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
或bool
, - 任何
enum
类型 - 任何指针类型,
- 任何用户定义的
struct
类型,仅包含非托管类型的字段.
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
, orbool
,- Any
enum
type, - Any pointer type,
- Any user-defined
struct
type that contains fields of unmanaged types only.
最后一点很关键,因为编译器必须能够验证您试图建立指针的struct
是合法的".否则,您将能够传递T
,它是struct
,其中的字段引用了被禁止的托管类型(例如,string
).
That last point is key, because the compiler must be able to verify that the struct
to which you are trying to make a pointer is "legal". Otherwise, you would be able to pass T
that is a struct
with fields referencing managed types (say, a string
) which is prohibited.
由于您有兴趣为四种数据类型提供此行为,因此您应该能够通过提供四种重载来解决此问题:
Since you are interested in providing this behavior for four data types, you should be able to address this problem by providing four overloads:
public int GetInt(int i) {
unsafe {
var p = (int*)hArr.ToPointer();
return *(p + i);
}
public void SetInt(int i, int val) {
unsafe {
var p = (int*)hArr.ToPointer();
*(p + i) = val;
}
}
public float GetFloat(int i) {
unsafe {
var p = (int*)hArr.ToPointer();
return *(p + i);
}
public void SetFloat(int i, float val) {
unsafe {
var p = (float*)hArr.ToPointer();
*(p + i) = val;
}
}
... // and so on
假设编译器具有足够的信息来解决编译时的重载,运行时效率将保持不变.
The run-time efficiency will remain the same, assuming that the compiler has enough information to resolve overloads at compile time.
这篇关于为什么不允许使用指向通用类型的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!