I have the following simple test:
class C<T>
{
public struct A
{
int x;
}
}
class Program
{
static unsafe void Main(string[] args)
{
IntPtr p = new IntPtr();
var a = (C<int>.A*)p.ToPointer();
}
}
The code generates error CS0208:
Cannot take the address of, get the size of, or declare a pointer to a managed
type ('C<int>.A')
Can anyone explain why the struct is considered "managed" in this scenario?
With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.
Basically, a class combines the fields and methods(member function which defines actions) into a single unit. A structure is a collection of variables of different data types under a single unit. It is almost similar to a class because both are user-defined data types and both hold a bunch of different data types.
Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created. 5) A struct is a value type. If you assign a struct to a new variable, the new variable will contain a copy of the original.
When you create a struct object using the new operator, it gets created and the appropriate constructor is called. Unlike classes, structs can be instantiated without using the new operator. If you do not use new, the fields will remain unassigned and the object cannot be used until all of the fields are initialized.
Section 18.2 of the C# 5 spec:
An unmanaged-type is any type that isn’t a reference-type or constructed type, and doesn’t contain reference-type or constructed type fields at any level of nesting.
Now you might wonder if C<int>.A
qualifies as a constructed type (its obviously not a reference type). The answer is yes. Section 4.4 defines constructed types. It specifically says nested types are considered constructed. It uses the Outer<T>.Inner
below as an example:
class Outer<T>
{
public class Inner {...}
public Inner i; // Type of i is Outer<T>.Inner
}
Because T
, which is part of C
is also part of A
. Which means A
is also generic. And all generic types are considered managed.
I guess, it would be possible to check if A
uses T
and decide on that. But as with all language features, it is feature, which's implementation would not have much return value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With