mscorlib(4.0.0.0) API with additions
CustomAttributeBuilder.cs
1 using System.Diagnostics;
2 using System.IO;
4 using System.Security;
6 using System.Text;
7 
9 {
11  [ClassInterface(ClassInterfaceType.None)]
12  [ComDefaultInterface(typeof(_CustomAttributeBuilder))]
13  [ComVisible(true)]
14  [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
16  {
17  internal ConstructorInfo m_con;
18 
19  internal object[] m_constructorArgs;
20 
21  internal byte[] m_blob;
22 
30  public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs)
31  {
32  InitCustomAttributeBuilder(con, constructorArgs, new PropertyInfo[0], new object[0], new FieldInfo[0], new object[0]);
33  }
34 
43  public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues)
44  {
45  InitCustomAttributeBuilder(con, constructorArgs, namedProperties, propertyValues, new FieldInfo[0], new object[0]);
46  }
47 
56  public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues)
57  {
58  InitCustomAttributeBuilder(con, constructorArgs, new PropertyInfo[0], new object[0], namedFields, fieldValues);
59  }
60 
71  public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues)
72  {
73  InitCustomAttributeBuilder(con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues);
74  }
75 
76  private bool ValidateType(Type t)
77  {
78  if (t.IsPrimitive || t == typeof(string) || t == typeof(Type))
79  {
80  return true;
81  }
82  if (t.IsEnum)
83  {
85  {
86  case TypeCode.SByte:
87  case TypeCode.Byte:
88  case TypeCode.Int16:
89  case TypeCode.UInt16:
90  case TypeCode.Int32:
91  case TypeCode.UInt32:
92  case TypeCode.Int64:
93  case TypeCode.UInt64:
94  return true;
95  default:
96  return false;
97  }
98  }
99  if (t.IsArray)
100  {
101  if (t.GetArrayRank() != 1)
102  {
103  return false;
104  }
105  return ValidateType(t.GetElementType());
106  }
107  return t == typeof(object);
108  }
109 
110  internal void InitCustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues)
111  {
112  if (con == null)
113  {
114  throw new ArgumentNullException("con");
115  }
116  if (constructorArgs == null)
117  {
118  throw new ArgumentNullException("constructorArgs");
119  }
120  if (namedProperties == null)
121  {
122  throw new ArgumentNullException("namedProperties");
123  }
124  if (propertyValues == null)
125  {
126  throw new ArgumentNullException("propertyValues");
127  }
128  if (namedFields == null)
129  {
130  throw new ArgumentNullException("namedFields");
131  }
132  if (fieldValues == null)
133  {
134  throw new ArgumentNullException("fieldValues");
135  }
136  if (namedProperties.Length != propertyValues.Length)
137  {
138  throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedProperties, propertyValues");
139  }
140  if (namedFields.Length != fieldValues.Length)
141  {
142  throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedFields, fieldValues");
143  }
144  if ((con.Attributes & MethodAttributes.Static) == MethodAttributes.Static || (con.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
145  {
146  throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructor"));
147  }
148  if ((con.CallingConvention & CallingConventions.Standard) != CallingConventions.Standard)
149  {
150  throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructorCallConv"));
151  }
152  m_con = con;
153  m_constructorArgs = new object[constructorArgs.Length];
154  Array.Copy(constructorArgs, m_constructorArgs, constructorArgs.Length);
155  Type[] parameterTypes = con.GetParameterTypes();
156  if (parameterTypes.Length != constructorArgs.Length)
157  {
158  throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterCountsForConstructor"));
159  }
160  for (int i = 0; i < parameterTypes.Length; i++)
161  {
162  if (!ValidateType(parameterTypes[i]))
163  {
164  throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
165  }
166  }
167  for (int i = 0; i < parameterTypes.Length; i++)
168  {
169  if (constructorArgs[i] != null)
170  {
171  TypeCode typeCode = Type.GetTypeCode(parameterTypes[i]);
172  if (typeCode != Type.GetTypeCode(constructorArgs[i].GetType()) && (typeCode != TypeCode.Object || !ValidateType(constructorArgs[i].GetType())))
173  {
174  throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForConstructor", i));
175  }
176  }
177  }
178  MemoryStream output = new MemoryStream();
179  BinaryWriter binaryWriter = new BinaryWriter(output);
180  binaryWriter.Write((ushort)1);
181  for (int i = 0; i < constructorArgs.Length; i++)
182  {
183  EmitValue(binaryWriter, parameterTypes[i], constructorArgs[i]);
184  }
185  binaryWriter.Write((ushort)(namedProperties.Length + namedFields.Length));
186  for (int i = 0; i < namedProperties.Length; i++)
187  {
188  if (namedProperties[i] == null)
189  {
190  throw new ArgumentNullException("namedProperties[" + i + "]");
191  }
192  Type propertyType = namedProperties[i].PropertyType;
193  if (propertyValues[i] == null && propertyType.IsPrimitive)
194  {
195  throw new ArgumentNullException("propertyValues[" + i + "]");
196  }
197  if (!ValidateType(propertyType))
198  {
199  throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
200  }
201  if (!namedProperties[i].CanWrite)
202  {
203  throw new ArgumentException(Environment.GetResourceString("Argument_NotAWritableProperty"));
204  }
205  if (namedProperties[i].DeclaringType != con.DeclaringType && !(con.DeclaringType is TypeBuilderInstantiation) && !con.DeclaringType.IsSubclassOf(namedProperties[i].DeclaringType) && !TypeBuilder.IsTypeEqual(namedProperties[i].DeclaringType, con.DeclaringType) && (!(namedProperties[i].DeclaringType is TypeBuilder) || !con.DeclaringType.IsSubclassOf(((TypeBuilder)namedProperties[i].DeclaringType).BakedRuntimeType)))
206  {
207  throw new ArgumentException(Environment.GetResourceString("Argument_BadPropertyForConstructorBuilder"));
208  }
209  if (propertyValues[i] != null && propertyType != typeof(object) && Type.GetTypeCode(propertyValues[i].GetType()) != Type.GetTypeCode(propertyType))
210  {
211  throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
212  }
213  binaryWriter.Write((byte)84);
214  EmitType(binaryWriter, propertyType);
215  EmitString(binaryWriter, namedProperties[i].Name);
216  EmitValue(binaryWriter, propertyType, propertyValues[i]);
217  }
218  for (int i = 0; i < namedFields.Length; i++)
219  {
220  if (namedFields[i] == null)
221  {
222  throw new ArgumentNullException("namedFields[" + i + "]");
223  }
224  Type fieldType = namedFields[i].FieldType;
225  if (fieldValues[i] == null && fieldType.IsPrimitive)
226  {
227  throw new ArgumentNullException("fieldValues[" + i + "]");
228  }
229  if (!ValidateType(fieldType))
230  {
231  throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
232  }
233  if (namedFields[i].DeclaringType != con.DeclaringType && !(con.DeclaringType is TypeBuilderInstantiation) && !con.DeclaringType.IsSubclassOf(namedFields[i].DeclaringType) && !TypeBuilder.IsTypeEqual(namedFields[i].DeclaringType, con.DeclaringType) && (!(namedFields[i].DeclaringType is TypeBuilder) || !con.DeclaringType.IsSubclassOf(((TypeBuilder)namedFields[i].DeclaringType).BakedRuntimeType)))
234  {
235  throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldForConstructorBuilder"));
236  }
237  if (fieldValues[i] != null && fieldType != typeof(object) && Type.GetTypeCode(fieldValues[i].GetType()) != Type.GetTypeCode(fieldType))
238  {
239  throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
240  }
241  binaryWriter.Write((byte)83);
242  EmitType(binaryWriter, fieldType);
243  EmitString(binaryWriter, namedFields[i].Name);
244  EmitValue(binaryWriter, fieldType, fieldValues[i]);
245  }
246  m_blob = ((MemoryStream)binaryWriter.BaseStream).ToArray();
247  }
248 
249  private void EmitType(BinaryWriter writer, Type type)
250  {
251  if (type.IsPrimitive)
252  {
253  switch (Type.GetTypeCode(type))
254  {
255  case TypeCode.SByte:
256  writer.Write((byte)4);
257  break;
258  case TypeCode.Byte:
259  writer.Write((byte)5);
260  break;
261  case TypeCode.Char:
262  writer.Write((byte)3);
263  break;
264  case TypeCode.Boolean:
265  writer.Write((byte)2);
266  break;
267  case TypeCode.Int16:
268  writer.Write((byte)6);
269  break;
270  case TypeCode.UInt16:
271  writer.Write((byte)7);
272  break;
273  case TypeCode.Int32:
274  writer.Write((byte)8);
275  break;
276  case TypeCode.UInt32:
277  writer.Write((byte)9);
278  break;
279  case TypeCode.Int64:
280  writer.Write((byte)10);
281  break;
282  case TypeCode.UInt64:
283  writer.Write((byte)11);
284  break;
285  case TypeCode.Single:
286  writer.Write((byte)12);
287  break;
288  case TypeCode.Double:
289  writer.Write((byte)13);
290  break;
291  }
292  }
293  else if (type.IsEnum)
294  {
295  writer.Write((byte)85);
296  EmitString(writer, type.AssemblyQualifiedName);
297  }
298  else if (type == typeof(string))
299  {
300  writer.Write((byte)14);
301  }
302  else if (type == typeof(Type))
303  {
304  writer.Write((byte)80);
305  }
306  else if (type.IsArray)
307  {
308  writer.Write((byte)29);
309  EmitType(writer, type.GetElementType());
310  }
311  else
312  {
313  writer.Write((byte)81);
314  }
315  }
316 
317  private void EmitString(BinaryWriter writer, string str)
318  {
319  byte[] bytes = Encoding.UTF8.GetBytes(str);
320  uint num = (uint)bytes.Length;
321  if (num <= 127)
322  {
323  writer.Write((byte)num);
324  }
325  else if (num <= 16383)
326  {
327  writer.Write((byte)((num >> 8) | 0x80));
328  writer.Write((byte)(num & 0xFF));
329  }
330  else
331  {
332  writer.Write((byte)((num >> 24) | 0xC0));
333  writer.Write((byte)((num >> 16) & 0xFF));
334  writer.Write((byte)((num >> 8) & 0xFF));
335  writer.Write((byte)(num & 0xFF));
336  }
337  writer.Write(bytes);
338  }
339 
340  private void EmitValue(BinaryWriter writer, Type type, object value)
341  {
342  if (type.IsEnum)
343  {
344  switch (Type.GetTypeCode(Enum.GetUnderlyingType(type)))
345  {
346  case TypeCode.SByte:
347  writer.Write((sbyte)value);
348  break;
349  case TypeCode.Byte:
350  writer.Write((byte)value);
351  break;
352  case TypeCode.Int16:
353  writer.Write((short)value);
354  break;
355  case TypeCode.UInt16:
356  writer.Write((ushort)value);
357  break;
358  case TypeCode.Int32:
359  writer.Write((int)value);
360  break;
361  case TypeCode.UInt32:
362  writer.Write((uint)value);
363  break;
364  case TypeCode.Int64:
365  writer.Write((long)value);
366  break;
367  case TypeCode.UInt64:
368  writer.Write((ulong)value);
369  break;
370  }
371  return;
372  }
373  if (type == typeof(string))
374  {
375  if (value == null)
376  {
377  writer.Write(byte.MaxValue);
378  }
379  else
380  {
381  EmitString(writer, (string)value);
382  }
383  return;
384  }
385  if (type == typeof(Type))
386  {
387  if (value == null)
388  {
389  writer.Write(byte.MaxValue);
390  return;
391  }
392  string text = TypeNameBuilder.ToString((Type)value, TypeNameBuilder.Format.AssemblyQualifiedName);
393  if (text == null)
394  {
395  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForCA", value.GetType()));
396  }
397  EmitString(writer, text);
398  return;
399  }
400  if (type.IsArray)
401  {
402  if (value == null)
403  {
404  writer.Write(uint.MaxValue);
405  return;
406  }
407  Array array = (Array)value;
408  Type elementType = type.GetElementType();
409  writer.Write(array.Length);
410  for (int i = 0; i < array.Length; i++)
411  {
412  EmitValue(writer, elementType, array.GetValue(i));
413  }
414  return;
415  }
416  if (type.IsPrimitive)
417  {
418  switch (Type.GetTypeCode(type))
419  {
420  case TypeCode.SByte:
421  writer.Write((sbyte)value);
422  break;
423  case TypeCode.Byte:
424  writer.Write((byte)value);
425  break;
426  case TypeCode.Char:
427  writer.Write(Convert.ToUInt16((char)value));
428  break;
429  case TypeCode.Boolean:
430  writer.Write((byte)(((bool)value) ? 1 : 0));
431  break;
432  case TypeCode.Int16:
433  writer.Write((short)value);
434  break;
435  case TypeCode.UInt16:
436  writer.Write((ushort)value);
437  break;
438  case TypeCode.Int32:
439  writer.Write((int)value);
440  break;
441  case TypeCode.UInt32:
442  writer.Write((uint)value);
443  break;
444  case TypeCode.Int64:
445  writer.Write((long)value);
446  break;
447  case TypeCode.UInt64:
448  writer.Write((ulong)value);
449  break;
450  case TypeCode.Single:
451  writer.Write((float)value);
452  break;
453  case TypeCode.Double:
454  writer.Write((double)value);
455  break;
456  }
457  return;
458  }
459  if (type == typeof(object))
460  {
461  Type type2 = (value == null) ? typeof(string) : ((value is Type) ? typeof(Type) : value.GetType());
462  if (type2 == typeof(object))
463  {
464  throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", type2.ToString()));
465  }
466  EmitType(writer, type2);
467  EmitValue(writer, type2, value);
468  return;
469  }
470  string text2 = "null";
471  if (value != null)
472  {
473  text2 = value.GetType().ToString();
474  }
475  throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", text2));
476  }
477 
478  [SecurityCritical]
479  internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner)
480  {
481  CreateCustomAttribute(mod, tkOwner, mod.GetConstructorToken(m_con).Token, toDisk: false);
482  }
483 
484  [SecurityCritical]
485  internal int PrepareCreateCustomAttributeToDisk(ModuleBuilder mod)
486  {
487  return mod.InternalGetConstructorToken(m_con, usingRef: true).Token;
488  }
489 
490  [SecurityCritical]
491  internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner, int tkAttrib, bool toDisk)
492  {
493  TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk, typeof(DebuggableAttribute) == m_con.DeclaringType);
494  }
495 
499  void _CustomAttributeBuilder.GetTypeInfoCount(out uint pcTInfo)
500  {
501  throw new NotImplementedException();
502  }
503 
509  void _CustomAttributeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
510  {
511  throw new NotImplementedException();
512  }
513 
521  void _CustomAttributeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
522  {
523  throw new NotImplementedException();
524  }
525 
536  void _CustomAttributeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
537  {
538  throw new NotImplementedException();
539  }
540  }
541 }
Represents a character encoding.To browse the .NET Framework source code for this type,...
Definition: Encoding.cs:15
bool IsPrimitive
Gets a value indicating whether the T:System.Type is one of the primitive types.
Definition: Type.cs:690
MethodAttributes
Specifies flags for method attributes. These flags are defined in the corhdr.h file.
virtual Stream BaseStream
Gets the underlying stream of the T:System.IO.BinaryWriter.
Definition: BinaryWriter.cs:44
CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues)
Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attr...
void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
Maps a set of names to a corresponding set of dispatch identifiers.
abstract Type GetElementType()
When overridden in a derived class, returns the T:System.Type of the object encompassed or referred t...
virtual byte [] GetBytes(char[] chars)
When overridden in a derived class, encodes all the characters in the specified character array into ...
Definition: Encoding.cs:1576
static TypeCode GetTypeCode(Type type)
Gets the underlying type code of the specified T:System.Type.
Definition: Type.cs:1199
TypeCode
Specifies the type of an object.
Definition: TypeCode.cs:9
void GetTypeInfoCount(out uint pcTInfo)
Retrieves the number of type information interfaces that an object provides (either 0 or 1).
Discovers the attributes of a class constructor and provides access to constructor metadata.
Discovers the attributes of a field and provides access to field metadata.
Definition: FieldInfo.cs:15
Definition: __Canon.cs:3
void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
Retrieves the type information for an object, which can be used to get the type information for an in...
virtual bool IsEnum
Gets a value indicating whether the current T:System.Type represents an enumeration.
Definition: Type.cs:484
virtual int GetArrayRank()
Gets the number of dimensions in an array.
Definition: Type.cs:1359
Modifies code generation for runtime just-in-time (JIT) debugging. This class cannot be inherited.
CallingConventions
Defines the valid calling conventions for a method.
SecurityAction
Specifies the security actions that can be performed using declarative security.
bool IsArray
Gets a value that indicates whether the type is an array.
Definition: Type.cs:551
Creates a stream whose backing store is memory.To browse the .NET Framework source code for this type...
Definition: MemoryStream.cs:13
A cast or conversion operation, such as (SampleType)obj in C::or CType(obj, SampleType) in Visual Bas...
CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues)
Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attr...
Provides the base class for enumerations.
Definition: Enum.cs:14
CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues)
Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attr...
CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs)
Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attr...
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
virtual void Write(bool value)
Writes a one-byte Boolean value to the current stream, with 0 representing false and 1 representing t...
void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
Provides access to properties and methods exposed by an object.
Exposes the T:System.Reflection.Emit.CustomAttributeBuilder class to unmanaged code.
Discovers the attributes of a property and provides access to property metadata.
Definition: PropertyInfo.cs:15
Type DeclaringType
Provides COM objects with version-independent access to the P:System.Reflection.MemberInfo....
Attribute can be applied to an enumeration.
static Encoding UTF8
Gets an encoding for the UTF-8 format.
Definition: Encoding.cs:1023
ClassInterfaceType
Identifies the type of class interface that is generated for a class.
static Type GetUnderlyingType(Type enumType)
Returns the underlying type of the specified enumeration.
Definition: Enum.cs:436
Writes primitive types in binary to a stream and supports writing strings in a specific encoding.
Definition: BinaryWriter.cs:12