Inner^ h; // C2248
This is a very common mistake in C++/CLI, a mistake that you can never make in other .NET languages like C# and VB.NET. Languages that automatically figure out whether a type is a value type or a reference type from the declaration. The hat was added to the C++/CLI syntax to make it resemble C++.
Creating a reference to a value type value requires the value to be stored on the garbage collected heap. This is called a "boxing conversion", the value is embedded in an object. Otherwise the magic that creates the illusion that a struct type inherits from ValueType which inherits from Object. Boxing conversions are needed in a few cases, such as calling the virtual methods inherited from System::Object (Equals, GetHashCode, ToString). Which the compiler takes care of without you helping, automatically emitting the boxing conversion code.
Intentionally boxing the value, like your statement does, has very few practical uses. I cannot think of any, but that's perhaps due to my lack of imagination. The boxing and unboxing code you will invoke, unseen, when accessing the variable just adds a lot of overhead that slows down your code. Value types were invented to speed-up code, you'll want to avoid boxing where you can.
Explaining the compiler error away is not so easy. One could argue that the compiler doesn't permit accessing the type internals that makes boxing possible because it is private. But hard to make that case, note that calling i.ToString()
produces the same error. While it is fine when it is a private reference type. Accessibility should never depend on the kind of type, this kind of inconsistency is usually called "bug" ;) You can post to connect.microsoft.com to make your case.
The best workaround is the sane one: just don't use the hat. Declare a reference type when you want reference semantics.