Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a nested struct inside a generic class considered "managed"?

Tags:

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?

like image 468
Timbo Avatar asked Aug 25 '14 08:08

Timbo


People also ask

When struct can be considered over a class?

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.

What is the difference between a class and a struct in C#?

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.

When would you use a struct?

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.

Can you call new on a struct?

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.


2 Answers

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
}
like image 65
Mike Zboray Avatar answered Sep 27 '22 18:09

Mike Zboray


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.

like image 24
Euphoric Avatar answered Sep 27 '22 19:09

Euphoric