comparison Source/Reflection/Emit/MethodBuilderHelper.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection.Emit;
5 using System.Reflection;
6
7 namespace BLToolkit.Reflection.Emit
8 {
9 /// <summary>
10 /// A wrapper around the <see cref="MethodBuilder"/> class.
11 /// </summary>
12 /// <include file="Examples.CS.xml" path='examples/emit[@name="Emit"]/*' />
13 /// <include file="Examples.VB.xml" path='examples/emit[@name="Emit"]/*' />
14 /// <seealso cref="System.Reflection.Emit.MethodBuilder">MethodBuilder Class</seealso>
15 public class MethodBuilderHelper : MethodBuilderBase
16 {
17 /// <summary>
18 /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class
19 /// with the specified parameters.
20 /// </summary>
21 /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param>
22 /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param>
23 public MethodBuilderHelper(TypeBuilderHelper typeBuilder, MethodBuilder methodBuilder)
24 : base(typeBuilder)
25 {
26 if (methodBuilder == null) throw new ArgumentNullException("methodBuilder");
27
28 _methodBuilder = methodBuilder;
29
30 methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute);
31 }
32
33 /// <summary>
34 /// Sets a custom attribute using a custom attribute type.
35 /// </summary>
36 /// <param name="attributeType">Attribute type.</param>
37 public void SetCustomAttribute(Type attributeType)
38 {
39 if (attributeType == null) throw new ArgumentNullException("attributeType");
40
41 ConstructorInfo ci = attributeType.GetConstructor(System.Type.EmptyTypes);
42 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(ci, new object[0]);
43
44 _methodBuilder.SetCustomAttribute(caBuilder);
45 }
46
47 /// <summary>
48 /// Sets a custom attribute using a custom attribute type
49 /// and named properties.
50 /// </summary>
51 /// <param name="attributeType">Attribute type.</param>
52 /// <param name="properties">Named properties of the custom attribute.</param>
53 /// <param name="propertyValues">Values for the named properties of the custom attribute.</param>
54 public void SetCustomAttribute(
55 Type attributeType,
56 PropertyInfo[] properties,
57 object[] propertyValues)
58 {
59 if (attributeType == null) throw new ArgumentNullException("attributeType");
60
61 ConstructorInfo ci = attributeType.GetConstructor(System.Type.EmptyTypes);
62 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(
63 ci, new object[0], properties, propertyValues);
64
65 _methodBuilder.SetCustomAttribute(caBuilder);
66 }
67
68 /// <summary>
69 /// Sets a custom attribute using a custom attribute type
70 /// and named property.
71 /// </summary>
72 /// <param name="attributeType">Attribute type.</param>
73 /// <param name="propertyName">A named property of the custom attribute.</param>
74 /// <param name="propertyValue">Value for the named property of the custom attribute.</param>
75 public void SetCustomAttribute(
76 Type attributeType,
77 string propertyName,
78 object propertyValue)
79 {
80 SetCustomAttribute(
81 attributeType,
82 new PropertyInfo[] { attributeType.GetProperty(propertyName) },
83 new object[] { propertyValue });
84 }
85
86 /// <summary>
87 /// Initializes a new instance of the <see cref="MethodBuilderHelper"/> class
88 /// with the specified parameters.
89 /// </summary>
90 /// <param name="typeBuilder">Associated <see cref="TypeBuilderHelper"/>.</param>
91 /// <param name="methodBuilder">A <see cref="MethodBuilder"/></param>
92 /// <param name="genericArguments">Generic arguments of the method.</param>
93 /// <param name="returnType">The return type of the method.</param>
94 /// <param name="parameterTypes">The types of the parameters of the method.</param>
95 internal MethodBuilderHelper(
96 TypeBuilderHelper typeBuilder,
97 MethodBuilder methodBuilder,
98 Type[] genericArguments,
99 Type returnType,
100 Type[] parameterTypes
101 )
102 : base(typeBuilder)
103 {
104 if (methodBuilder == null) throw new ArgumentNullException("methodBuilder");
105 if (genericArguments == null) throw new ArgumentNullException("genericArguments");
106
107 _methodBuilder = methodBuilder;
108
109 var genArgNames = genericArguments.Select(t => t.Name).ToArray();
110 var genParams = methodBuilder.DefineGenericParameters(genArgNames);
111
112 // Copy parameter constraints.
113 //
114 List<Type> interfaceConstraints = null;
115
116 for (var i = 0; i < genParams.Length; i++)
117 {
118 genParams[i].SetGenericParameterAttributes(genericArguments[i].GenericParameterAttributes);
119
120 foreach (var constraint in genericArguments[i].GetGenericParameterConstraints())
121 {
122 if (constraint.IsClass)
123 genParams[i].SetBaseTypeConstraint(constraint);
124 else
125 {
126 if (interfaceConstraints == null)
127 interfaceConstraints = new List<Type>();
128 interfaceConstraints.Add(constraint);
129 }
130 }
131
132 if (interfaceConstraints != null && interfaceConstraints.Count != 0)
133 {
134 genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray());
135 interfaceConstraints.Clear();
136 }
137 }
138
139 // When a method contains a generic parameter we need to replace all
140 // generic types from methodInfoDeclaration with local ones.
141 //
142 for (var i = 0; i < parameterTypes.Length; i++)
143 parameterTypes[i] = TypeHelper.TranslateGenericParameters(parameterTypes[i], genParams);
144
145 methodBuilder.SetParameters(parameterTypes);
146 methodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters(returnType, genParams));
147
148 // Once all generic stuff is done is it is safe to call SetCustomAttribute
149 //
150 methodBuilder.SetCustomAttribute(Type.Assembly.BLToolkitAttribute);
151 }
152
153 private readonly MethodBuilder _methodBuilder;
154 /// <summary>
155 /// Gets MethodBuilder.
156 /// </summary>
157 public MethodBuilder MethodBuilder
158 {
159 get { return _methodBuilder; }
160 }
161
162 /// <summary>
163 /// Converts the supplied <see cref="MethodBuilderHelper"/> to a <see cref="MethodBuilder"/>.
164 /// </summary>
165 /// <param name="methodBuilder">The <see cref="MethodBuilderHelper"/>.</param>
166 /// <returns>A <see cref="MethodBuilder"/>.</returns>
167 public static implicit operator MethodBuilder(MethodBuilderHelper methodBuilder)
168 {
169 if (methodBuilder == null) throw new ArgumentNullException("methodBuilder");
170
171 return methodBuilder.MethodBuilder;
172 }
173
174 private EmitHelper _emitter;
175 /// <summary>
176 /// Gets <see cref="EmitHelper"/>.
177 /// </summary>
178 public override EmitHelper Emitter
179 {
180 get
181 {
182 if (_emitter == null)
183 _emitter = new EmitHelper(this, _methodBuilder.GetILGenerator());
184
185 return _emitter;
186 }
187 }
188
189 private MethodInfo _overriddenMethod;
190 /// <summary>
191 /// Gets or sets the base type method overridden by this method, if any.
192 /// </summary>
193 public MethodInfo OverriddenMethod
194 {
195 get { return _overriddenMethod; }
196 set { _overriddenMethod = value; }
197 }
198
199 /// <summary>
200 /// Returns the type that declares this method.
201 /// </summary>
202 public Type DeclaringType
203 {
204 get { return _methodBuilder.DeclaringType; }
205 }
206 }
207 }