Mercurial > pub > bltoolkit
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 } |