1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 // 6 // Activator is an object that contains the Activation (CreateInstance/New) 7 // methods for late bound support. 8 // 9 10 using System.Diagnostics; 11 using System.Globalization; 12 using System.Reflection; 13 using System.Runtime.CompilerServices; 14 using System.Runtime; 15 16 using Internal.Reflection.Augments; 17 18 namespace System 19 { 20 public static class Activator 21 { 22 // The following 2 methods and helper class implement the functionality of Activator.CreateInstance<T>() 23 24 // This method is the public surface area. It wraps the CreateInstance intrinsic with the appropriate try/catch 25 // block so that the correct exceptions are generated. Also, it handles the cases where the T type doesn't have 26 // a default constructor. (Those result in running the ClassWithMissingConstructor's .ctor, which flips the magic 27 // thread static to cause the CreateInstance<T> method to throw the right exception.) 28 // 29 [DebuggerGuidedStepThrough] CreateInstance()30 public static T CreateInstance<T>() 31 { 32 T t = default(T); 33 34 bool missingDefaultConstructor = false; 35 36 EETypePtr eetype = EETypePtr.EETypePtrOf<T>(); 37 38 if (!RuntimeHelpers.IsReference<T>()) 39 { 40 // Early out for valuetypes since we don't support default constructors anyway. 41 // This lets codegens that expand IsReference<T> optimize away the rest of this code. 42 } 43 else if (eetype.ComponentSize != 0) 44 { 45 // ComponentSize > 0 indicates an array-like type (e.g. string, array, etc). 46 // Allocating this using the normal allocator would result in silent heap corruption. 47 missingDefaultConstructor = true; 48 } 49 else if (eetype.IsInterface) 50 { 51 // Do not attempt to allocate interface types either 52 missingDefaultConstructor = true; 53 } 54 else 55 { 56 bool oldValueOfMissingDefaultCtorMarkerBool = s_createInstanceMissingDefaultConstructor; 57 58 try 59 { 60 #if PROJECTN 61 t = CreateInstanceIntrinsic<T>(); 62 DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); 63 #else 64 t = (T)(RuntimeImports.RhNewObject(eetype)); 65 66 // Run the default constructor. If the default constructor was missing, codegen 67 // will expand DefaultConstructorOf to ClassWithMissingConstructor::.ctor 68 // and we detect that later. 69 IntPtr defaultConstructor = DefaultConstructorOf<T>(); 70 RawCalliHelper.Call(defaultConstructor, t); 71 DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); 72 #endif 73 } 74 catch (Exception e) 75 { 76 throw new TargetInvocationException(e); 77 } 78 79 if (s_createInstanceMissingDefaultConstructor != oldValueOfMissingDefaultCtorMarkerBool) 80 { 81 missingDefaultConstructor = true; 82 83 // We didn't call the real .ctor (because there wasn't one), but we still allocated 84 // an uninitialized object. If it has a finalizer, it would run - prevent that. 85 GC.SuppressFinalize(t); 86 } 87 } 88 89 if (missingDefaultConstructor) 90 { 91 throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, typeof(T))); 92 } 93 94 return t; 95 } 96 97 [Intrinsic] CreateInstanceIntrinsic()98 private extern static T CreateInstanceIntrinsic<T>(); 99 100 [Intrinsic] DefaultConstructorOf()101 private static IntPtr DefaultConstructorOf<T>() 102 { 103 // Codegens must expand this intrinsic. 104 // We could implement a fallback with the type loader if we wanted to, but it will be slow and unreliable. 105 throw new NotSupportedException(); 106 } 107 108 [ThreadStatic] 109 internal static bool s_createInstanceMissingDefaultConstructor; 110 internal class ClassWithMissingConstructor 111 { ClassWithMissingConstructor()112 private ClassWithMissingConstructor() 113 { 114 s_createInstanceMissingDefaultConstructor = !s_createInstanceMissingDefaultConstructor; 115 } MissingDefaultConstructorStaticEntryPoint()116 internal static void MissingDefaultConstructorStaticEntryPoint() 117 { 118 s_createInstanceMissingDefaultConstructor = !s_createInstanceMissingDefaultConstructor; 119 } 120 } 121 122 [DebuggerHidden] 123 [DebuggerStepThrough] 124 public static object CreateInstance(Type type) => CreateInstance(type, nonPublic: false); 125 126 [DebuggerHidden] 127 [DebuggerStepThrough] CreateInstance(Type type, bool nonPublic)128 public static object CreateInstance(Type type, bool nonPublic) => ReflectionAugments.ReflectionCoreCallbacks.ActivatorCreateInstance(type, nonPublic); 129 130 [DebuggerHidden] 131 [DebuggerStepThrough] CreateInstance(Type type, params object[] args)132 public static object CreateInstance(Type type, params object[] args) => CreateInstance(type, ConstructorDefault, null, args, null, null); 133 134 [DebuggerHidden] 135 [DebuggerStepThrough] CreateInstance(Type type, object[] args, object[] activationAttributes)136 public static object CreateInstance(Type type, object[] args, object[] activationAttributes) => CreateInstance(type, ConstructorDefault, null, args, null, activationAttributes); 137 138 [DebuggerHidden] 139 [DebuggerStepThrough] CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture)140 public static object CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture) => CreateInstance(type, bindingAttr, binder, args, culture, null); 141 142 [DebuggerHidden] 143 [DebuggerStepThrough] CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)144 public static object CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes) 145 { 146 return ReflectionAugments.ReflectionCoreCallbacks.ActivatorCreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); 147 } 148 149 private const BindingFlags ConstructorDefault = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance; 150 } 151 } 152 153