2 // PropertyInfoTest.cs - NUnit Test Cases for PropertyInfo
5 // Gert Driesen (drieseng@users.sourceforge.net)
7 // (C) 2004-2007 Gert Driesen
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Reflection
;
32 using System
.Runtime
.InteropServices
;
33 using System
.Threading
;
35 using System
.Reflection
.Emit
;
39 using NUnit
.Framework
;
41 namespace MonoTests
.System
.Reflection
44 public class PropertyInfoTest
47 public void GetAccessorsTest ()
49 Type type
= typeof (TestClass
);
50 PropertyInfo property
= type
.GetProperty ("ReadOnlyProperty");
52 MethodInfo
[] methods
= property
.GetAccessors (true);
53 Assert
.AreEqual (1, methods
.Length
, "#A1");
54 Assert
.IsNotNull (methods
[0], "#A2");
55 Assert
.AreEqual ("get_ReadOnlyProperty", methods
[0].Name
, "#A3");
57 methods
= property
.GetAccessors (false);
58 Assert
.AreEqual (1, methods
.Length
, "#B1");
59 Assert
.IsNotNull (methods
[0], "#B2");
60 Assert
.AreEqual ("get_ReadOnlyProperty", methods
[0].Name
, "#B3");
62 property
= typeof (Base
).GetProperty ("P");
64 methods
= property
.GetAccessors (true);
65 Assert
.AreEqual (2, methods
.Length
, "#C1");
66 Assert
.IsNotNull (methods
[0], "#C2");
67 Assert
.IsNotNull (methods
[1], "#C3");
68 Assert
.IsTrue (HasMethod (methods
, "get_P"), "#C4");
69 Assert
.IsTrue (HasMethod (methods
, "set_P"), "#C5");
71 methods
= property
.GetAccessors (false);
72 Assert
.AreEqual (2, methods
.Length
, "#D1");
73 Assert
.IsNotNull (methods
[0], "#D2");
74 Assert
.IsNotNull (methods
[1], "#D3");
75 Assert
.IsTrue (HasMethod (methods
, "get_P"), "#D4");
76 Assert
.IsTrue (HasMethod (methods
, "set_P"), "#D5");
78 methods
= property
.GetAccessors ();
79 Assert
.AreEqual (2, methods
.Length
, "#E1");
80 Assert
.IsNotNull (methods
[0], "#E2");
81 Assert
.IsNotNull (methods
[1], "#E3");
82 Assert
.IsTrue (HasMethod (methods
, "get_P"), "#E4");
83 Assert
.IsTrue (HasMethod (methods
, "set_P"), "#E5");
85 property
= typeof (TestClass
).GetProperty ("Private",
86 BindingFlags
.NonPublic
| BindingFlags
.Instance
);
88 methods
= property
.GetAccessors (true);
89 Assert
.AreEqual (2, methods
.Length
, "#F1");
90 Assert
.IsNotNull (methods
[0], "#F2");
91 Assert
.IsNotNull (methods
[1], "#F3");
92 Assert
.IsTrue (HasMethod (methods
, "get_Private"), "#F4");
93 Assert
.IsTrue (HasMethod (methods
, "set_Private"), "#F5");
95 methods
= property
.GetAccessors (false);
96 Assert
.AreEqual (0, methods
.Length
, "#G");
98 methods
= property
.GetAccessors ();
99 Assert
.AreEqual (0, methods
.Length
, "#H");
102 property
= typeof (TestClass
).GetProperty ("PrivateSetter");
104 methods
= property
.GetAccessors (true);
105 Assert
.AreEqual (2, methods
.Length
, "#H1");
106 Assert
.IsNotNull (methods
[0], "#H2");
107 Assert
.IsNotNull (methods
[1], "#H3");
108 Assert
.IsTrue (HasMethod (methods
, "get_PrivateSetter"), "#H4");
109 Assert
.IsTrue (HasMethod (methods
, "set_PrivateSetter"), "#H5");
111 methods
= property
.GetAccessors (false);
112 Assert
.AreEqual (1, methods
.Length
, "#I1");
113 Assert
.IsNotNull (methods
[0], "#I2");
114 Assert
.AreEqual ("get_PrivateSetter", methods
[0].Name
, "#I3");
116 methods
= property
.GetAccessors ();
117 Assert
.AreEqual (1, methods
.Length
, "#J1");
118 Assert
.IsNotNull (methods
[0], "#J2");
119 Assert
.AreEqual ("get_PrivateSetter", methods
[0].Name
, "#J3");
124 public void GetCustomAttributes ()
127 PropertyInfo p
= typeof (Base
).GetProperty ("P");
129 attrs
= p
.GetCustomAttributes (false);
130 Assert
.AreEqual (1, attrs
.Length
, "#A1");
131 Assert
.AreEqual (typeof (ThisAttribute
), attrs
[0].GetType (), "#A2");
132 attrs
= p
.GetCustomAttributes (true);
133 Assert
.AreEqual (1, attrs
.Length
, "#A3");
134 Assert
.AreEqual (typeof (ThisAttribute
), attrs
[0].GetType (), "#A4");
136 p
= typeof (Base
).GetProperty ("T");
138 attrs
= p
.GetCustomAttributes (false);
139 Assert
.AreEqual (2, attrs
.Length
, "#B1");
140 Assert
.IsTrue (HasAttribute (attrs
, typeof (ThisAttribute
)), "#B2");
141 Assert
.IsTrue (HasAttribute (attrs
, typeof (ComVisibleAttribute
)), "#B3");
142 attrs
= p
.GetCustomAttributes (true);
143 Assert
.AreEqual (2, attrs
.Length
, "#B41");
144 Assert
.IsTrue (HasAttribute (attrs
, typeof (ThisAttribute
)), "#B5");
145 Assert
.IsTrue (HasAttribute (attrs
, typeof (ComVisibleAttribute
)), "#B6");
147 p
= typeof (Base
).GetProperty ("Z");
149 attrs
= p
.GetCustomAttributes (false);
150 Assert
.AreEqual (0, attrs
.Length
, "#C1");
151 attrs
= p
.GetCustomAttributes (true);
152 Assert
.AreEqual (0, attrs
.Length
, "#C2");
156 public void GetCustomAttributes_Inherited ()
159 PropertyInfo p
= typeof (Derived
).GetProperty ("P");
161 attrs
= p
.GetCustomAttributes (false);
162 Assert
.AreEqual (0, attrs
.Length
, "#A1");
163 attrs
= p
.GetCustomAttributes (true);
164 Assert
.AreEqual (0, attrs
.Length
, "#A3");
166 p
= typeof (Derived
).GetProperty ("T");
168 attrs
= p
.GetCustomAttributes (false);
169 Assert
.AreEqual (2, attrs
.Length
, "#B1");
170 Assert
.IsTrue (HasAttribute (attrs
, typeof (ThisAttribute
)), "#B2");
171 Assert
.IsTrue (HasAttribute (attrs
, typeof (ComVisibleAttribute
)), "#B3");
172 attrs
= p
.GetCustomAttributes (true);
173 Assert
.AreEqual (2, attrs
.Length
, "#B41");
174 Assert
.IsTrue (HasAttribute (attrs
, typeof (ThisAttribute
)), "#B5");
175 Assert
.IsTrue (HasAttribute (attrs
, typeof (ComVisibleAttribute
)), "#B6");
177 p
= typeof (Derived
).GetProperty ("Z");
179 attrs
= p
.GetCustomAttributes (false);
180 Assert
.AreEqual (0, attrs
.Length
, "#C1");
181 attrs
= p
.GetCustomAttributes (true);
182 Assert
.AreEqual (0, attrs
.Length
, "#C2");
186 public void IsDefined_AttributeType_Null ()
188 Type derived
= typeof (Derived
);
189 PropertyInfo pi
= derived
.GetProperty ("P");
192 pi
.IsDefined ((Type
) null, false);
194 } catch (ArgumentNullException ex
) {
195 Assert
.AreEqual (typeof (ArgumentNullException
), ex
.GetType (), "#2");
196 Assert
.IsNull (ex
.InnerException
, "#3");
197 Assert
.IsNotNull (ex
.Message
, "#4");
198 Assert
.IsNotNull (ex
.ParamName
, "#5");
199 Assert
.AreEqual ("attributeType", ex
.ParamName
, "#6");
204 public void AccessorsReflectedType ()
206 PropertyInfo pi
= typeof (Derived
).GetProperty ("T");
207 Assert
.AreEqual (typeof (Derived
), pi
.GetGetMethod ().ReflectedType
);
208 Assert
.AreEqual (typeof (Derived
), pi
.GetSetMethod ().ReflectedType
);
211 [Test
] // bug #399985
212 public void SetValue_Enum ()
214 TestClass t
= new TestClass ();
215 PropertyInfo pi
= t
.GetType ().GetProperty ("Targets");
216 pi
.SetValue (t
, AttributeTargets
.Field
, null);
217 Assert
.AreEqual (AttributeTargets
.Field
, t
.Targets
, "#1");
218 pi
.SetValue (t
, (int) AttributeTargets
.Interface
, null);
219 Assert
.AreEqual (AttributeTargets
.Interface
, t
.Targets
, "#2");
222 public class ThisAttribute
: Attribute
229 public virtual string P
{
236 public virtual string T
{
241 public virtual string Z
{
249 public override string P
{
255 static void RunTest (Type t
, bool use_getter
) {
256 var p
= t
.GetProperty ("Item");
257 var idx
= p
.GetIndexParameters ();
258 var m_args
= t
.GetMethod (use_getter
? "get_Item" : "set_Item").GetParameters ();
260 Assert
.AreEqual (2, idx
.Length
, "#1");
262 Assert
.AreEqual (typeof (double), idx
[0].ParameterType
, "#2");
263 Assert
.AreEqual (p
, idx
[0].Member
, "#3");
264 Assert
.AreEqual ("a", idx
[0].Name
, "#4");
265 Assert
.AreEqual (0, idx
[0].Position
, "#5");
266 Assert
.AreEqual (m_args
[0].MetadataToken
, idx
[0].MetadataToken
, "#6");
267 Assert
.AreEqual (ParameterAttributes
.None
, idx
[0].Attributes
, "#7");
269 Assert
.AreEqual (typeof (string), idx
[1].ParameterType
, "#8");
270 Assert
.AreEqual (p
, idx
[1].Member
, "#9");
271 Assert
.AreEqual ("b", idx
[1].Name
, "#10");
272 Assert
.AreEqual (1, idx
[1].Position
, "#11");
273 Assert
.AreEqual (m_args
[1].MetadataToken
, idx
[1].MetadataToken
, "#12");
274 Assert
.AreEqual (ParameterAttributes
.None
, idx
[1].Attributes
, "#13");
276 var idx2
= p
.GetIndexParameters ();
278 //No interning exposed
279 Assert
.AreNotSame (idx
, idx2
, "#14");
280 Assert
.AreNotSame (idx
[0], idx2
[1], "#15");
284 public void GetIndexParameterReturnsObjectsBoundToTheProperty ()
286 RunTest (typeof (TestA
), false);
287 RunTest (typeof (TestB
), true);
291 public int this[double a
, string b
] {
297 public int this[double a
, string b
] {
304 public void GetIndexParameterReturnedObjectsCustomAttributes () {
305 var pa
= typeof (TestC
).GetProperty ("Item").GetIndexParameters () [0];
306 Assert
.IsTrue (pa
.IsDefined (typeof (ParamArrayAttribute
), false), "#1");
308 var pb
= typeof (TestD
).GetProperty ("Item").GetIndexParameters () [0];
309 Assert
.IsTrue (pb
.IsDefined (typeof (ParamArrayAttribute
), false), "#2");
311 Assert
.AreEqual (1, Attribute
.GetCustomAttributes (pa
).Length
, "#3");
312 Assert
.AreEqual (1, Attribute
.GetCustomAttributes (pb
).Length
, "#4");
314 Assert
.AreEqual (0, pa
.GetOptionalCustomModifiers ().Length
, "#5");
315 Assert
.AreEqual (0, pb
.GetRequiredCustomModifiers ().Length
, "#6");
319 public int this[params double[] a
] {
325 public int this[params double[] a
] {
330 static string CreateTempAssembly ()
341 path
= Path
.Combine (Path
.GetTempPath (), "tmp" + num
.ToString ("x") + ".dll");
344 f
= new FileStream (path
, FileMode
.CreateNew
);
351 return "tmp" + num
.ToString ("x") + ".dll";
361 public void ConstantValue () {
362 /*This test looks scary because we can't generate a default value with C# */
363 var assemblyName
= new AssemblyName ();
364 assemblyName
.Name
= "MonoTests.System.Reflection.Emit.PropertyInfoTest";
365 string an
= CreateTempAssembly ();
367 var assembly
= Thread
.GetDomain ().DefineDynamicAssembly (assemblyName
, AssemblyBuilderAccess
.RunAndSave
, Path
.GetTempPath ());
368 var module
= assembly
.DefineDynamicModule ("module1", an
);
370 var tb
= module
.DefineType ("Test", TypeAttributes
.Public
);
371 var prop
= tb
.DefineProperty ("Prop", PropertyAttributes
.HasDefault
, typeof (string), new Type
[0]);
373 var getter
= tb
.DefineMethod ("get_Prop", MethodAttributes
.Public
, typeof (string), new Type
[0]);
374 var ilgen
= getter
.GetILGenerator ();
375 ilgen
.Emit (OpCodes
.Ldnull
);
376 ilgen
.Emit (OpCodes
.Ret
);
378 var setter
= tb
.DefineMethod ("set_Prop", MethodAttributes
.Public
, null, new Type
[1] { typeof (string) }
);
379 setter
.GetILGenerator ().Emit (OpCodes
.Ret
);
381 prop
.SetConstant ("test");
382 prop
.SetGetMethod (getter
);
383 prop
.SetSetMethod (setter
);
387 File
.Delete (Path
.Combine (Path
.GetTempPath (), an
));
390 var asm
= Assembly
.LoadFrom (Path
.Combine (Path
.GetTempPath (), an
));
391 var t
= asm
.GetType ("Test");
392 var p
= t
.GetProperty ("Prop");
393 Assert
.AreEqual ("test", p
.GetConstantValue (), "#1");
395 File
.Delete (Path
.Combine (Path
.GetTempPath (), an
));
397 var pa
= typeof (TestE
).GetProperty ("PropE");
399 pa
.GetConstantValue ();
401 } catch (InvalidOperationException
) {
408 public string Property
{
409 get { return typeof (T).FullName; }
413 public int? nullable_field
;
415 public int? NullableProperty
{
416 get { return nullable_field; }
417 set { nullable_field = value; }
421 public void NullableTests ()
423 PropertyInfoTest t
= new PropertyInfoTest ();
425 PropertyInfo pi
= typeof(PropertyInfoTest
).GetProperty("NullableProperty");
427 pi
.SetValue (t
, 100, null);
428 Assert
.AreEqual (100, pi
.GetValue (t
, null));
429 pi
.SetValue (t
, null, null);
430 Assert
.AreEqual (null, pi
.GetValue (t
, null));
434 public void Bug77160 ()
436 object instance
= new A
<string> ();
437 Type type
= instance
.GetType ();
438 PropertyInfo property
= type
.GetProperty ("Property");
439 Assert
.AreEqual (typeof (string).FullName
, property
.GetValue (instance
, null));
444 static bool HasAttribute (object [] attrs
, Type attributeType
)
446 foreach (object attr
in attrs
)
447 if (attr
.GetType () == attributeType
)
452 static bool HasMethod (MethodInfo
[] methods
, string name
)
454 foreach (MethodInfo method
in methods
)
455 if (method
.Name
== name
)
460 private class TestClass
462 private AttributeTargets _targets
= AttributeTargets
.Assembly
;
464 public AttributeTargets Targets
{
465 get { return _targets; }
466 set { _targets = value; }
469 public string ReadOnlyProperty
{
470 get { return string.Empty; }
473 private string Private
{
479 public string PrivateSetter
{
486 [Test
] // bug #633671
487 public void DeclaringTypeOfPropertyFromInheritedTypePointsToBase ()
489 var inherit1
= typeof(InheritsFromClassWithNullableDateTime
);
490 var siblingProperty
= inherit1
.GetProperty("Property1");
492 Assert
.AreEqual (typeof (ClassWithNullableDateTime
), siblingProperty
.DeclaringType
, "#1");
493 Assert
.AreEqual (typeof (InheritsFromClassWithNullableDateTime
), siblingProperty
.ReflectedType
, "#2");
495 //The check is done twice since the bug is related to getting those 2 properties multiple times.
496 Assert
.AreEqual (typeof (ClassWithNullableDateTime
), siblingProperty
.DeclaringType
, "#3");
497 Assert
.AreEqual (typeof (InheritsFromClassWithNullableDateTime
), siblingProperty
.ReflectedType
, "#4");
501 public class ClassWithNullableDateTime
503 public DateTime
? Property1 { get; set; }
506 public class InheritsFromClassWithNullableDateTime
: ClassWithNullableDateTime
510 public static int ThrowingProperty
{
512 throw new ObjectDisposedException("TestClass");
517 public void GetException () {
518 var prop
= typeof(PropertyInfoTest
).GetProperty("ThrowingProperty");
520 prop
.GetValue (null, null);
522 } catch (TargetInvocationException ex
) {
523 Assert
.IsTrue (ex
.InnerException
is ObjectDisposedException
);