为什么不允许使用指向通用类型的指针? [英] Why is pointer to generic types not allowed?

查看:117
本文介绍了为什么不允许使用指向通用类型的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,作为重载的[] 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

  • sbytebyteshortushortintuintlongulongcharfloatdoubledecimalbool
  • 任何enum类型
  • 任何指针类型,
  • 任何用户定义的struct类型,仅包含非托管类型的字段.
  • sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool,
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆