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.

Suman Banerjee
  • 1,923
  • 4
  • 24
  • 40
sgtz
  • 8,849
  • 9
  • 51
  • 91
  • Generics and `unsafe` do not mix well. You'd need a `where TIn : blittable` constraint which doesn't exist ([Blittable and Non-Blittable Types](http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx)). What are you trying to achieve? – dtb Sep 05 '11 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. – leppie Sep 05 '11 at 11:20
  • converter logic for arrays of n dimensions, for a set of about a dozen types. Pointers would have been ideal. – sgtz Sep 05 '11 at 11:20
  • @dtb: thanks for pointing out "blittable". Just updated the question above with this information. – sgtz Sep 05 '11 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... – MattDavey May 15 '12 at 17:16
  • See http://stackoverflow.com/questions/4994277/memory-address-of-an-object-in-c-sharp – Jay May 04 '16 at 01:01

1 Answers1

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?

Community
  • 1
  • 1
Adam Wright
  • 48,938
  • 12
  • 131
  • 152
  • 6
    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. – msedi Mar 25 '12 at 11:19
  • 2
    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. – Dr. Andrew Burnett-Thompson Oct 20 '13 at 19:51
  • 1
    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. – Walt D May 31 '16 at 20:35