Or are you just saying that you can 'use' them via out/ref? I interpreted your post to mean that you can store them in fields, which would be stellar but seems like it would break reference lifetime guarantees.
- Managed pointers can be passed as arguments, stored in local variables, and returned as values.
- Managed pointers cannot be stored in static variables, array elements, or fields of objects or value types.
So you're right, they have very limited scope as it'd be messy otherwise. It's my understanding that the JVM does not have pointers even at this level, hence Java can't do out/ref parameters. (Sure, tuples are a better way to handle many cases of out params, but sometimes a well chosen ref can really be nicer.)
I think C++ also uses the term "managed pointer" but not in the same technical sense (I think it just means reference.) Using "safe" C++/CLI generation limits the scope of pointers just like we'd expect.
You can if you mark the containing class/struct "unsafe", which allows both type safety and increased ease of use.
using System;
namespace Test2012
{
unsafe class C { public byte* P; public override string ToString( ) { return new IntPtr(P).ToString( ); } }
unsafe struct S { public byte* P; public override string ToString( ) { return new IntPtr(P).ToString( ); } }
static class Program
{
static unsafe void Main( )
{
fixed( byte* test = new byte[] { 1, 2, 3 } )
{
var c = new C( ) { P = test };
var s = new S( ) { P = test };
Console.WriteLine( "Test: {0}", c );
Console.WriteLine( "Test: {0}", s );
}
}
}
}
Result: Test: 40510364
Test: 40510364
Press any key to continue . . .
However, you have to declare an 'unsafe' context in which you'll do it. Unsafe contexts are tied to a local scope, which means that you can't do anything like having classes with fields of pointer types. Pointers don't outlive the function in which you use them.
Also, before you can get a pointer to an object you have to "pin" it, which tells the garbage collector not to move it around. This is necessary, of course, but it can have severe performance implications since it basically torpedoes all the garbage collector's best performance optimizations.
So pointers are there when you need them. . . but the language makes them extremely inconvenient to use them more than you absolutely need to. A pretty solid compromise, IMO.