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 using System; 6 using System.Reflection; 7 using System.Diagnostics; 8 using System.Collections.Generic; 9 using System.Runtime.CompilerServices; 10 using System.Reflection.Runtime.General; 11 using System.Reflection.Runtime.TypeInfos; 12 using System.Reflection.Runtime.ParameterInfos; 13 using System.Reflection.Runtime.CustomAttributes; 14 15 using Internal.Reflection.Core.Execution; 16 using Internal.Reflection.Tracing; 17 18 namespace System.Reflection.Runtime.EventInfos 19 { 20 // 21 // The runtime's implementation of EventInfo's 22 // 23 [DebuggerDisplay("{_debugName}")] 24 internal abstract partial class RuntimeEventInfo : EventInfo, ITraceableTypeMember 25 { RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType)26 protected RuntimeEventInfo(RuntimeTypeInfo contextTypeInfo, RuntimeTypeInfo reflectedType) 27 { 28 ContextTypeInfo = contextTypeInfo; 29 ReflectedTypeInfo = reflectedType; 30 } 31 32 public sealed override MethodInfo AddMethod 33 { 34 get 35 { 36 #if ENABLE_REFLECTION_TRACE 37 if (ReflectionTrace.Enabled) 38 ReflectionTrace.EventInfo_AddMethod(this); 39 #endif 40 41 MethodInfo adder = _lazyAdder; 42 if (adder == null) 43 { 44 adder = GetEventMethod(EventMethodSemantics.Add); 45 if (adder != null) 46 return _lazyAdder = adder; 47 48 throw new BadImageFormatException(); // Added is a required method. 49 } 50 return adder; 51 } 52 } 53 54 public sealed override Type DeclaringType 55 { 56 get 57 { 58 #if ENABLE_REFLECTION_TRACE 59 if (ReflectionTrace.Enabled) 60 ReflectionTrace.EventInfo_DeclaringType(this); 61 #endif 62 63 return ContextTypeInfo; 64 } 65 } 66 GetOtherMethods(bool nonPublic)67 public sealed override MethodInfo[] GetOtherMethods(bool nonPublic) 68 { 69 throw new PlatformNotSupportedException(); 70 } 71 HasSameMetadataDefinitionAs(MemberInfo other)72 public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other); 73 74 public sealed override Module Module 75 { 76 get 77 { 78 return DefiningTypeInfo.Module; 79 } 80 } 81 82 public sealed override String Name 83 { 84 get 85 { 86 #if ENABLE_REFLECTION_TRACE 87 if (ReflectionTrace.Enabled) 88 ReflectionTrace.EventInfo_Name(this); 89 #endif 90 91 return MetadataName; 92 } 93 } 94 95 public sealed override Type ReflectedType 96 { 97 get 98 { 99 return ReflectedTypeInfo; 100 } 101 } 102 103 public sealed override MethodInfo RaiseMethod 104 { 105 get 106 { 107 #if ENABLE_REFLECTION_TRACE 108 if (ReflectionTrace.Enabled) 109 ReflectionTrace.EventInfo_RaiseMethod(this); 110 #endif 111 112 return GetEventMethod(EventMethodSemantics.Fire); 113 } 114 } 115 116 public sealed override MethodInfo RemoveMethod 117 { 118 get 119 { 120 #if ENABLE_REFLECTION_TRACE 121 if (ReflectionTrace.Enabled) 122 ReflectionTrace.EventInfo_RemoveMethod(this); 123 #endif 124 125 MethodInfo remover = _lazyRemover; 126 if (remover == null) 127 { 128 remover = GetEventMethod(EventMethodSemantics.Remove); 129 if (remover != null) 130 return _lazyRemover = remover; 131 132 throw new BadImageFormatException(); // Removed is a required method. 133 } 134 return remover; 135 } 136 } 137 ToString()138 public sealed override String ToString() 139 { 140 MethodInfo addMethod = this.AddMethod; 141 ParameterInfo[] parameters = addMethod.GetParametersNoCopy(); 142 if (parameters.Length == 0) 143 throw new InvalidOperationException(); // Legacy: Why is a ToString() intentionally throwing an exception? 144 RuntimeParameterInfo runtimeParameterInfo = (RuntimeParameterInfo)(parameters[0]); 145 return runtimeParameterInfo.ParameterTypeString + " " + this.Name; 146 } 147 148 String ITraceableTypeMember.MemberName 149 { 150 get 151 { 152 return MetadataName; 153 } 154 } 155 156 Type ITraceableTypeMember.ContainingType 157 { 158 get 159 { 160 return ContextTypeInfo; 161 } 162 } 163 WithDebugName()164 protected RuntimeEventInfo WithDebugName() 165 { 166 bool populateDebugNames = DeveloperExperienceState.DeveloperExperienceModeEnabled; 167 #if DEBUG 168 populateDebugNames = true; 169 #endif 170 if (!populateDebugNames) 171 return this; 172 173 if (_debugName == null) 174 { 175 _debugName = "Constructing..."; // Protect against any inadvertent reentrancy. 176 _debugName = MetadataName; 177 } 178 return this; 179 } 180 181 // Types that derive from RuntimeEventInfo must implement the following public surface area members 182 public abstract override EventAttributes Attributes { get; } 183 public abstract override IEnumerable<CustomAttributeData> CustomAttributes { get; } Equals(Object obj)184 public abstract override bool Equals(Object obj); GetHashCode()185 public abstract override int GetHashCode(); 186 public abstract override Type EventHandlerType { get; } 187 public abstract override int MetadataToken { get; } 188 189 protected enum EventMethodSemantics 190 { 191 Add, 192 Remove, 193 Fire 194 } 195 196 /// <summary> 197 /// Override to return the Method that corresponds to the specified semantic. 198 /// Return null if no method is to be found. 199 /// </summary> GetEventMethod(EventMethodSemantics whichMethod)200 protected abstract MethodInfo GetEventMethod(EventMethodSemantics whichMethod); 201 202 /// <summary> 203 /// Override to provide the metadata based name of an event. (Different from the Name 204 /// property in that it does not go into the reflection trace logic.) 205 /// </summary> 206 protected abstract string MetadataName { get; } 207 208 /// <summary> 209 /// Return the DefiningTypeInfo as a RuntimeTypeInfo (instead of as a format specific type info) 210 /// </summary> 211 protected abstract RuntimeTypeInfo DefiningTypeInfo { get; } 212 213 214 protected readonly RuntimeTypeInfo ContextTypeInfo; 215 protected readonly RuntimeTypeInfo ReflectedTypeInfo; 216 217 private volatile MethodInfo _lazyAdder; 218 private volatile MethodInfo _lazyRemover; 219 220 private String _debugName; 221 } 222 } 223