4

I'd like to create a generic method that uses a pointer to an array of T where T could be a C# primitive, or a C# class. I was going along fine until I attempted the "T" part.

Is there a way around the error "can not declare a pointer to a non unmanaged type TIn"

I tried to use pinning via the "fixed" keyword to make this possible.

    public static object DoSomething<TIn, TOut>(object SObj, Action<TIn, TOut> takeAction)
    {
        double[]A = (double[]) SObj;
        TIn[]B = new TIn[5];
        unsafe
        {
            fixed (double* dbl = A) // <--- works okay
            {

            }
            fixed (TIn* Sptr = B)  // <--- fails
            {

            }
        }
    }

--

@dtb: just checked out blittable. "One-dimensional arrays of blittable types, such as an array of integers. However, a type that contains a variable array of blittable types is not itself blittable." Even if there was a biltable constraint, it seems like they've limited it to arrays of one dimension.

6
  • Generics and unsafe do not mix well. You'd need a where TIn : blittable constraint which doesn't exist (Blittable and Non-Blittable Types). What are you trying to achieve? Commented Sep 5, 2011 at 11:18
  • Pointers to generic types are not support. That what the compiler will tell you too. Nothing you can do about it. Just generate concrete types. Commented Sep 5, 2011 at 11:20
  • converter logic for arrays of n dimensions, for a set of about a dozen types. Pointers would have been ideal. Commented Sep 5, 2011 at 11:20
  • @dtb: thanks for pointing out "blittable". Just updated the question above with this information. Commented Sep 5, 2011 at 11:30
  • You can sort of do this by using a void* pointer, you just need to remember to cast it back to concrete type pointer afterwards... Commented May 15, 2012 at 17:16

1 Answer 1

6

Essentially, no. You can't create a pointer to a managed type - only to certain primitive types and structs where all the fields are themselves structs or unmanaged types. Your generic parameter type will not have these properties, so it forbids construction of a pointer and gives you that error.

As per http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx, pointers can be made to:

  • 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.

Fortunately, as pointer arithmetic is impossible, there's not a whole lot of benefit to having a pointer to a managed type. Why do you want to build one?

Sign up to request clarification or add additional context in comments.

3 Comments

There of course a benefit. Using pointers for casting data is a factor of 2 to 3 in performance compared to all other available methods in .NET or C#. In fact I don't know reason why it should not be possible to have arithmetic operations on pointers. Do you why there is no arimetic value type or a blittable datatype. For me it seems that performance for most of the developers here is not such a big issue since they are not dealing with a large amount of data.
Another benefit. Say I have an array TY[] which is actually a double array. I want to take a pointer to TY and perform operations on it.
It is true that you can't declare a pointer of type T*, but you can still get a pointer of type IntPtr to a generic T[] array by using the GCHandle class to pin the array and then retrieve the pointer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.