public static T CreateInstance <T>() { if (!RuntimeHelpers.IsReference <T>()) { // Early out for valuetypes since we don't support default constructors anyway for now. // This lets codegens that expand IsReference<T> optimize away the rest of this code. return(default);
public static unsafe T CreateInstance <[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>() { // Grab the pointer to the default constructor of the type. If T doesn't have a default // constructor, the intrinsic returns a marker pointer that we check for. IntPtr defaultConstructor = DefaultConstructorOf <T>(); // Check if we got the marker back. // // TODO: might want to disambiguate the different cases for abstract class, interface, etc. if (defaultConstructor == (IntPtr)(delegate * < Guid >) & MissingConstructorMethod) { throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, typeof(T))); } T t; try { // Call the default constructor on the allocated instance. if (RuntimeHelpers.IsReference <T>()) { // Grab a pointer to the optimized allocator for the type and call it. IntPtr allocator = AllocatorOf <T>(); t = RawCalliHelper.Call <T>(allocator, EETypePtr.EETypePtrOf <T>().RawValue); RawCalliHelper.Call(defaultConstructor, t); // Debugger goo so that stepping in works. Only affects debug info generation. // The call gets optimized away. DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); } else { t = default !;
public static T CreateInstance <T>() { T t = default(T); bool missingDefaultConstructor = false; EETypePtr eetype = EETypePtr.EETypePtrOf <T>(); if (!RuntimeHelpers.IsReference <T>()) { // Early out for valuetypes since we don't support default constructors anyway. // This lets codegens that expand IsReference<T> optimize away the rest of this code. } else if (eetype.ComponentSize != 0) { // ComponentSize > 0 indicates an array-like type (e.g. string, array, etc). // Allocating this using the normal allocator would result in silent heap corruption. missingDefaultConstructor = true; } else if (eetype.IsInterface) { // Do not attempt to allocate interface types either missingDefaultConstructor = true; } else { bool oldValueOfMissingDefaultCtorMarkerBool = s_createInstanceMissingDefaultConstructor; try { t = (T)(RuntimeImports.RhNewObject(eetype)); // Run the default constructor. If the default constructor was missing, codegen // will expand DefaultConstructorOf to ClassWithMissingConstructor::.ctor // and we detect that later. IntPtr defaultConstructor = DefaultConstructorOf <T>(); RawCalliHelper.Call(defaultConstructor, t); DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); } catch (Exception e) { throw new TargetInvocationException(e); } if (s_createInstanceMissingDefaultConstructor != oldValueOfMissingDefaultCtorMarkerBool) { missingDefaultConstructor = true; // We didn't call the real .ctor (because there wasn't one), but we still allocated // an uninitialized object. If it has a finalizer, it would run - prevent that. GC.SuppressFinalize(t); } } if (missingDefaultConstructor) { throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, typeof(T))); } return(t); }