introspection into Types, Methods, and Parameters is a very useful feature for the creation of highly dynamic programs. One use for this ability is to allow generic methods to be highly expansive.
Take for example, a function that wants to read in an object, and initialize the properties and fields of that object to data stored elsewhere. Perhaps a database, or maybe a dictionary or some other data structure. At any rate, it wants to be able to instantiate and create an instance and populate that instance without actually knowing the specific type at compile time.
The first step to such a method would be to instantiate the class. The most straightforward way would be to acquire the parameterless constructor, and invoke it- the result will be the constructed object.
This approach does, however, have some undesirable curve-balls that can bite you. Observe in this example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ class Program { static void Main(string[] args) { Type[] ConstructType = new Type[] { typeof(SimpleClass), typeof(SimpleStruct) }; foreach (Type constructtype in ConstructType) { //get parameterless constructor. ConstructorInfo constructinfo = constructtype.GetConstructor(new Type[0]); if (constructinfo == null) { Console.WriteLine("parameterless constructor not present on type " + constructtype.Name); } else { Object created = constructinfo.Invoke(new object[] { }); Console.WriteLine("Created Object:" + created.ToString()); } } Console.ReadKey(); } } public class SimpleClass { public override string ToString() { return "SimpleClass"; } } public struct SimpleStruct { public override string ToString() { return "SimpleStruct"; } } |
The result of running this program is the following output:
1 2 |
Created Object:SimpleClass parameterless constructor not present on type SimpleStruct |
What is going on here? Why is the class instantiatable, but not the struct, even though they are exactly the same? Both can be instantiated using new SimpleClass() or new SimpleStruct() in the code- why does reflection claim things that don’t seem to make sense?
The reason appears to be partly because of how unreliably the constructor is called in certain circumstances by the CLR, as well as how defining a parameterless constructor in such a way pragmatically makes that struct “mutable”, which can cause issues when dealing with value-type assignment, (which copies the struct, rather than copying a reference to the struct). In order to stay as consistent as possible, the C# compiler does not emit a constructor for any value types and instead relies on the standard CLR struct initialization. As a result, you can’t define one yourself. Jon Skeet provides a far more in depth look at the underpinnings that are the cause of this particular result.
At any rate: the reason you don’t see a constructor when reflecting on a C# type is because C# doesn’t emit constructors on value types
Have something to say about this post? Comment!