Generics and unsafe pointers

  • Thread starter Thread starter Greg Myers
  • Start date Start date
G

Greg Myers

Hello, I'm a noob to C# programming and was wondering if there was a
way around a problem I'm having. The following code snippet shows the
problem:

public class MyType<T> where T:struct
{
unsafe private T* mVar;

unsafe public MyType( ref T var )
{
fixed( T* address = &var )
{
mVar = address;
}
}
}

The compiler complains that I "Cannot take the address of, get the
size of, or declare a pointer to a managed type ('T')" even though my
where clause specifies that T must be a basic type. Is there a way
around this or do I just need to change my design? Thanks in advance
for any info provided.

Greg
 
[...]
public class MyType<T> where T:struct
{
unsafe private T* mVar;

unsafe public MyType( ref T var )
{
fixed( T* address = &var )
{
mVar = address;
}
}
}

The compiler complains that I "Cannot take the address of, get the
size of, or declare a pointer to a managed type ('T')" even though my
where clause specifies that T must be a basic type.

First, your constraint doesn't restrict T to "a basic type". It restricts
it to a "struct", or "value type". It would be a mistake to assume that
just because something is a value type, it's "basic" (whatever is meant by
that...the fact is, the word "basic" has no precise definition in this
context).

Second, when taking the address of a variable typed as a struct, the
struct must contain only fields of unmanaged types (basically, the GC
ignores pointer types, and so they can't point to things that might
contain GC-managed objects). With a generic type, the compiler has no way
to verify that's the case. There's no constraint that embodies that
requirement.
Is there a way around this or do I just need to change my design?

I can't think of any way around it that would still allow the benefits of
a generic type. The very things that make generics useful are mututally
exclusive with unsafe code.

Personally, I would look for solutions that don't involve unsafe code.
IMHO, "unsafe" is over-used in C#, usually not needed even though someone
thinks it is. On the other hand, the benefit of generics to the quality
of the code is significant.

If you feel that you really must use unsafe code here, a generic type
isn't going to work. It may be that C++/CLI is a better choice for your
code; there, you should be able to code your generic type as a template
instead, which has different compile-time requirements than generics do
(specifically, verification of the safety of the code would be deferred
until the actual usage of the template, allowing more flexibility in what
code can be exist in the templte itself).

Pete
 
My apologies to both rossum and Pete, I clicked the "Reply to author"
button by mistake when responding.

Thanks to both of you for the information.

Pete,

I meant to say "value type" but I goofed. Sorry for the confusion.
I'll look into just using C++/CLI for what I'm trying to do. It will
probably result in a smoother transition.


rossum,

I guess my understanding of "fixed" statements and C# in general are
really lacking. ;) I'll have to go study up some more. Thanks for
pointing that out for me. With that being the case ( var being moved
by the GC ) I can be guarranteed a catastrophic failure.

Thanks guys,
Greg
 
Back
Top