It has everything to do with the difference between classes and structs. A struct is a value type. It means, that as soon as you declare it, memory is allocated for that struct. So in your case, the memory required for the MyStruct.a is allocated within the memory of the instance of Test, when the instance of Test is created.
The memory for class instances (reference type) is only allocated when you create the instance (new). So you can't access any member (field or method or ...) before it's created.
Theoretically, the code for both a struct and a class should be available, but for classes that code needs information from the instance to call the method, e.g. to find out which (virtual) method actually to call.
It also has to do with the difference between allocating and initializing a variable. When you've allocated memory for a variable, you can use that variable, even though you might not know what the contents are. When you've initialized a variable, you actually know what the contents are, so you can use it AND get predictable results.
Initializing a variable is done automatically for some variables and you need to do it yourself for others (e.g. local variables). I don't know the reason for this, but just accept it ;) If you don't initialize a variable that should be initialized, the compiler helps you with a build error.
I hope this helps for you.
Mystruct st;) the structure will be initialized with zeros; when declared as a local variable the structure will not be initialized (will contain trash)