com.wallstop-studios.unity-helpers 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/AGENTS.md +1 -0
  2. package/Docs/ILIST_SORTING_PERFORMANCE.md +16 -16
  3. package/Docs/INDEX.md +1 -0
  4. package/Docs/RANDOM_PERFORMANCE.md +15 -15
  5. package/Docs/REFLECTION_HELPERS.md +84 -1
  6. package/Docs/REFLECTION_PERFORMANCE.md +169 -0
  7. package/{package-lock.json.meta → Docs/REFLECTION_PERFORMANCE.md.meta} +1 -1
  8. package/Docs/RELATIONAL_COMPONENTS.md +6 -0
  9. package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md +63 -0
  10. package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md.meta +7 -0
  11. package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +64 -64
  12. package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +64 -64
  13. package/Editor/Sprites/AnimationCopier.cs +1 -1
  14. package/Editor/Sprites/AnimationViewerWindow.cs +4 -4
  15. package/Editor/Sprites/SpriteSettingsApplierAPI.cs +2 -1
  16. package/Editor/Sprites/TextureResizerWizard.cs +4 -3
  17. package/Editor/Utils/ScriptableObjectSingletonCreator.cs +3 -3
  18. package/README.md +8 -3
  19. package/Runtime/Core/Attributes/BaseRelationalComponentAttribute.cs +147 -20
  20. package/Runtime/Core/Attributes/ChildComponentAttribute.cs +630 -117
  21. package/Runtime/Core/Attributes/NotNullAttribute.cs +5 -2
  22. package/Runtime/Core/Attributes/ParentComponentAttribute.cs +477 -103
  23. package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +26 -3
  24. package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +19 -3
  25. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +265 -92
  26. package/Runtime/Core/CodeGen.meta +8 -0
  27. package/Runtime/Core/DataStructure/ImmutableBitSet.cs +5 -20
  28. package/Runtime/Core/Helper/Helpers.cs +8 -0
  29. package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +11 -7
  30. package/Runtime/Core/Helper/Objects.cs +1 -1
  31. package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs +5142 -0
  32. package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs.meta +11 -0
  33. package/Runtime/Core/Helper/ReflectionHelpers.cs +1812 -1518
  34. package/Runtime/Core/Math/Line2D.cs +2 -4
  35. package/Runtime/Core/Math/Line3D.cs +2 -4
  36. package/Runtime/Core/Random/FlurryBurstRandom.cs +0 -6
  37. package/Runtime/Tags/AttributeMetadataCache.cs +4 -6
  38. package/Runtime/Tags/CosmeticEffectData.cs +1 -1
  39. package/Runtime/Visuals/UIToolkit/MultiFileSelectorElement.cs +3 -3
  40. package/Tests/Editor/Helper/HelpersTests.cs +2 -2
  41. package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs +87 -0
  42. package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs.meta +11 -0
  43. package/Tests/Editor/Helper/SpriteHelpersTests.cs +1 -1
  44. package/Tests/Editor/PrefabCheckerReportTests.cs +3 -3
  45. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +18 -12
  46. package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +8 -7
  47. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +2 -1
  48. package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +6 -5
  49. package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +2 -1
  50. package/Tests/Editor/Sprites/SpriteCropperTests.cs +7 -6
  51. package/Tests/Editor/Sprites/SpritePivotAdjusterAdditionalTests.cs +2 -1
  52. package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +4 -3
  53. package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +10 -9
  54. package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +2 -1
  55. package/Tests/Runtime/Helper/ObjectsTests.cs +1 -1
  56. package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs +2923 -0
  57. package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs.meta +11 -0
  58. package/Tests/Runtime/Helper/ReflectionHelperTests.cs +660 -0
  59. package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs +1238 -0
  60. package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs.meta +11 -0
  61. package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs +832 -0
  62. package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs.meta +11 -0
  63. package/package.json +1 -1
  64. package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs +0 -60
  65. package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs.meta +0 -3
@@ -0,0 +1,2923 @@
1
+ namespace WallstopStudios.UnityHelpers.Tests.Helper
2
+ {
3
+ using System;
4
+ using System.Collections;
5
+ using System.Collections.Generic;
6
+ using System.Reflection;
7
+ using NUnit.Framework;
8
+ using WallstopStudios.UnityHelpers.Core.Helper;
9
+
10
+ [TestFixture]
11
+ public sealed class ReflectionHelperCapabilityMatrixTests
12
+ {
13
+ public enum CapabilityMode
14
+ {
15
+ [Obsolete("Use a concrete capability mode.", false)]
16
+ Unknown = 0,
17
+ Expressions = 1,
18
+ DynamicIl = 2,
19
+ Reflection = 3,
20
+ }
21
+
22
+ private static readonly CapabilityMode[] CapabilityModes =
23
+ {
24
+ CapabilityMode.Expressions,
25
+ CapabilityMode.DynamicIl,
26
+ CapabilityMode.Reflection,
27
+ };
28
+
29
+ [SetUp]
30
+ public void ResetCaches()
31
+ {
32
+ ReflectionHelpers.ClearFieldGetterCache();
33
+ ReflectionHelpers.ClearFieldSetterCache();
34
+ ReflectionHelpers.ClearPropertyCache();
35
+ ReflectionHelpers.ClearMethodCache();
36
+ ReflectionHelpers.ClearConstructorCache();
37
+ }
38
+
39
+ [TestCaseSource(nameof(CapabilityModes))]
40
+ public void FieldGetterBoxedSupportsCapabilities(CapabilityMode mode)
41
+ {
42
+ RunInCapabilityMode(
43
+ mode,
44
+ () =>
45
+ {
46
+ TestClass instance = new() { intValue = 37 };
47
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
48
+ Func<object, object> getter = ReflectionHelpers.GetFieldGetter(field);
49
+ Assert.AreEqual(37, getter(instance));
50
+ }
51
+ );
52
+ }
53
+
54
+ [TestCaseSource(nameof(CapabilityModes))]
55
+ public void FieldSetterBoxedSupportsCapabilities(CapabilityMode mode)
56
+ {
57
+ RunInCapabilityMode(
58
+ mode,
59
+ () =>
60
+ {
61
+ TestClass instance = new();
62
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
63
+ Action<object, object> setter = ReflectionHelpers.GetFieldSetter(field);
64
+ setter(instance, 91);
65
+ Assert.AreEqual(91, instance.intValue);
66
+ }
67
+ );
68
+ }
69
+
70
+ [TestCaseSource(nameof(CapabilityModes))]
71
+ public void FieldGetterTypedSupportsCapabilities(CapabilityMode mode)
72
+ {
73
+ RunInCapabilityMode(
74
+ mode,
75
+ () =>
76
+ {
77
+ TestClass instance = new() { intValue = 73 };
78
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
79
+ Func<TestClass, int> getter = ReflectionHelpers.GetFieldGetter<TestClass, int>(
80
+ field
81
+ );
82
+ Assert.AreEqual(73, getter(instance));
83
+ }
84
+ );
85
+ }
86
+
87
+ [TestCaseSource(nameof(CapabilityModes))]
88
+ public void FieldSetterTypedSupportsCapabilities(CapabilityMode mode)
89
+ {
90
+ RunInCapabilityMode(
91
+ mode,
92
+ () =>
93
+ {
94
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
95
+ FieldSetter<TestClass, int> setter = ReflectionHelpers.GetFieldSetter<
96
+ TestClass,
97
+ int
98
+ >(field);
99
+ TestClass instance = new();
100
+ setter(ref instance, 82);
101
+ Assert.AreEqual(82, instance.intValue);
102
+ }
103
+ );
104
+ }
105
+
106
+ [TestCaseSource(nameof(CapabilityModes))]
107
+ public void StaticFieldGetterBoxedSupportsCapabilities(CapabilityMode mode)
108
+ {
109
+ int original = TestClass.StaticIntValue;
110
+ try
111
+ {
112
+ TestClass.StaticIntValue = 144;
113
+ RunInCapabilityMode(
114
+ mode,
115
+ () =>
116
+ {
117
+ FieldInfo field = typeof(TestClass).GetField(
118
+ nameof(TestClass.StaticIntValue),
119
+ BindingFlags.Static | BindingFlags.Public
120
+ );
121
+ Func<object> getter = ReflectionHelpers.GetStaticFieldGetter(field);
122
+ Assert.AreEqual(144, getter());
123
+ }
124
+ );
125
+ }
126
+ finally
127
+ {
128
+ TestClass.StaticIntValue = original;
129
+ }
130
+ }
131
+
132
+ [TestCaseSource(nameof(CapabilityModes))]
133
+ public void StaticFieldSetterBoxedSupportsCapabilities(CapabilityMode mode)
134
+ {
135
+ int original = TestClass.StaticIntValue;
136
+ try
137
+ {
138
+ RunInCapabilityMode(
139
+ mode,
140
+ () =>
141
+ {
142
+ FieldInfo field = typeof(TestClass).GetField(
143
+ nameof(TestClass.StaticIntValue),
144
+ BindingFlags.Static | BindingFlags.Public
145
+ );
146
+ Action<object> setter = ReflectionHelpers.GetStaticFieldSetter(field);
147
+ setter(256);
148
+ Assert.AreEqual(256, TestClass.StaticIntValue);
149
+ }
150
+ );
151
+ }
152
+ finally
153
+ {
154
+ TestClass.StaticIntValue = original;
155
+ }
156
+ }
157
+
158
+ [TestCaseSource(nameof(CapabilityModes))]
159
+ public void StaticFieldGetterTypedSupportsCapabilities(CapabilityMode mode)
160
+ {
161
+ int original = TestClass.StaticIntValue;
162
+ try
163
+ {
164
+ TestClass.StaticIntValue = 512;
165
+ RunInCapabilityMode(
166
+ mode,
167
+ () =>
168
+ {
169
+ FieldInfo field = typeof(TestClass).GetField(
170
+ nameof(TestClass.StaticIntValue),
171
+ BindingFlags.Static | BindingFlags.Public
172
+ );
173
+ Func<int> getter = ReflectionHelpers.GetStaticFieldGetter<int>(field);
174
+ Assert.AreEqual(512, getter());
175
+ }
176
+ );
177
+ }
178
+ finally
179
+ {
180
+ TestClass.StaticIntValue = original;
181
+ }
182
+ }
183
+
184
+ [TestCaseSource(nameof(CapabilityModes))]
185
+ public void StaticFieldSetterTypedSupportsCapabilities(CapabilityMode mode)
186
+ {
187
+ int original = TestClass.StaticIntValue;
188
+ try
189
+ {
190
+ RunInCapabilityMode(
191
+ mode,
192
+ () =>
193
+ {
194
+ FieldInfo field = typeof(TestClass).GetField(
195
+ nameof(TestClass.StaticIntValue),
196
+ BindingFlags.Static | BindingFlags.Public
197
+ );
198
+ Action<int> setter = ReflectionHelpers.GetStaticFieldSetter<int>(field);
199
+ setter(1024);
200
+ Assert.AreEqual(1024, TestClass.StaticIntValue);
201
+ }
202
+ );
203
+ }
204
+ finally
205
+ {
206
+ TestClass.StaticIntValue = original;
207
+ }
208
+ }
209
+
210
+ [Test]
211
+ public void FieldGetterCachesRemainStrategyScoped()
212
+ {
213
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
214
+ Func<object, object> expressionGetter;
215
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
216
+ {
217
+ expressionGetter = ReflectionHelpers.GetFieldGetter(field);
218
+ }
219
+
220
+ Func<object, object> dynamicGetter;
221
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
222
+ {
223
+ dynamicGetter = ReflectionHelpers.GetFieldGetter(field);
224
+ }
225
+
226
+ Func<object, object> reflectionGetter;
227
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
228
+ {
229
+ reflectionGetter = ReflectionHelpers.GetFieldGetter(field);
230
+ }
231
+
232
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
233
+ Assert.That(
234
+ ReflectionHelpers.TryGetDelegateStrategy(expressionGetter, out expressionStrategy),
235
+ Is.True
236
+ );
237
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
238
+ Assert.That(
239
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
240
+ Is.True
241
+ );
242
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
243
+ Assert.That(
244
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionGetter, out reflectionStrategy),
245
+ Is.True
246
+ );
247
+
248
+ Assume.That(
249
+ expressionStrategy,
250
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
251
+ "Expression delegates are unavailable on this platform."
252
+ );
253
+ Assume.That(
254
+ dynamicStrategy,
255
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
256
+ "Dynamic IL delegates are unavailable on this platform."
257
+ );
258
+ Assert.That(
259
+ reflectionStrategy,
260
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
261
+ );
262
+
263
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
264
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
265
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
266
+
267
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
268
+ {
269
+ Func<object, object> expressionGetterSecond = ReflectionHelpers.GetFieldGetter(
270
+ field
271
+ );
272
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
273
+ }
274
+
275
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
276
+ {
277
+ Func<object, object> dynamicGetterSecond = ReflectionHelpers.GetFieldGetter(field);
278
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
279
+ }
280
+
281
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
282
+ {
283
+ Func<object, object> reflectionGetterSecond = ReflectionHelpers.GetFieldGetter(
284
+ field
285
+ );
286
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
287
+ }
288
+
289
+ Assert.That(ReflectionHelpers.IsFieldGetterCached(field), Is.True);
290
+ }
291
+
292
+ [Test]
293
+ public void FieldSetterCachesRemainStrategyScoped()
294
+ {
295
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
296
+ Action<object, object> expressionSetter;
297
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
298
+ {
299
+ expressionSetter = ReflectionHelpers.GetFieldSetter(field);
300
+ }
301
+
302
+ Action<object, object> dynamicSetter;
303
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
304
+ {
305
+ dynamicSetter = ReflectionHelpers.GetFieldSetter(field);
306
+ }
307
+
308
+ Action<object, object> reflectionSetter;
309
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
310
+ {
311
+ reflectionSetter = ReflectionHelpers.GetFieldSetter(field);
312
+ }
313
+
314
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
315
+ Assert.That(
316
+ ReflectionHelpers.TryGetDelegateStrategy(expressionSetter, out expressionStrategy),
317
+ Is.True
318
+ );
319
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
320
+ Assert.That(
321
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
322
+ Is.True
323
+ );
324
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
325
+ Assert.That(
326
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionSetter, out reflectionStrategy),
327
+ Is.True
328
+ );
329
+
330
+ Assume.That(
331
+ expressionStrategy,
332
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
333
+ "Expression delegates are unavailable on this platform."
334
+ );
335
+ Assume.That(
336
+ dynamicStrategy,
337
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
338
+ "Dynamic IL delegates are unavailable on this platform."
339
+ );
340
+ Assert.That(
341
+ reflectionStrategy,
342
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
343
+ );
344
+
345
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
346
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
347
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
348
+
349
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
350
+ {
351
+ Action<object, object> expressionSetterSecond = ReflectionHelpers.GetFieldSetter(
352
+ field
353
+ );
354
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
355
+ }
356
+
357
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
358
+ {
359
+ Action<object, object> dynamicSetterSecond = ReflectionHelpers.GetFieldSetter(
360
+ field
361
+ );
362
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
363
+ }
364
+
365
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
366
+ {
367
+ Action<object, object> reflectionSetterSecond = ReflectionHelpers.GetFieldSetter(
368
+ field
369
+ );
370
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
371
+ }
372
+
373
+ Assert.That(ReflectionHelpers.IsFieldSetterCached(field), Is.True);
374
+ }
375
+
376
+ [Test]
377
+ public void FieldGetterTypedCachesRemainStrategyScoped()
378
+ {
379
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
380
+ Func<TestClass, int> expressionGetter;
381
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
382
+ {
383
+ expressionGetter = ReflectionHelpers.GetFieldGetter<TestClass, int>(field);
384
+ }
385
+
386
+ Func<TestClass, int> dynamicGetter;
387
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
388
+ {
389
+ dynamicGetter = ReflectionHelpers.GetFieldGetter<TestClass, int>(field);
390
+ }
391
+
392
+ Func<TestClass, int> reflectionGetter;
393
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
394
+ {
395
+ reflectionGetter = ReflectionHelpers.GetFieldGetter<TestClass, int>(field);
396
+ }
397
+
398
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
399
+ Assert.That(
400
+ ReflectionHelpers.TryGetDelegateStrategy(expressionGetter, out expressionStrategy),
401
+ Is.True
402
+ );
403
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
404
+ Assert.That(
405
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
406
+ Is.True
407
+ );
408
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
409
+ Assert.That(
410
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionGetter, out reflectionStrategy),
411
+ Is.True
412
+ );
413
+
414
+ Assume.That(
415
+ expressionStrategy,
416
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
417
+ "Expression delegates are unavailable on this platform."
418
+ );
419
+ Assume.That(
420
+ dynamicStrategy,
421
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
422
+ "Dynamic IL delegates are unavailable on this platform."
423
+ );
424
+ Assert.That(
425
+ reflectionStrategy,
426
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
427
+ );
428
+
429
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
430
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
431
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
432
+
433
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
434
+ {
435
+ Func<TestClass, int> expressionGetterSecond = ReflectionHelpers.GetFieldGetter<
436
+ TestClass,
437
+ int
438
+ >(field);
439
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
440
+ }
441
+
442
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
443
+ {
444
+ Func<TestClass, int> dynamicGetterSecond = ReflectionHelpers.GetFieldGetter<
445
+ TestClass,
446
+ int
447
+ >(field);
448
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
449
+ }
450
+
451
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
452
+ {
453
+ Func<TestClass, int> reflectionGetterSecond = ReflectionHelpers.GetFieldGetter<
454
+ TestClass,
455
+ int
456
+ >(field);
457
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
458
+ }
459
+ }
460
+
461
+ [Test]
462
+ public void FieldSetterTypedCachesRemainStrategyScoped()
463
+ {
464
+ FieldInfo field = typeof(TestClass).GetField(nameof(TestClass.intValue));
465
+ FieldSetter<TestClass, int> expressionSetter;
466
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
467
+ {
468
+ expressionSetter = ReflectionHelpers.GetFieldSetter<TestClass, int>(field);
469
+ }
470
+
471
+ FieldSetter<TestClass, int> dynamicSetter;
472
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
473
+ {
474
+ dynamicSetter = ReflectionHelpers.GetFieldSetter<TestClass, int>(field);
475
+ }
476
+
477
+ FieldSetter<TestClass, int> reflectionSetter;
478
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
479
+ {
480
+ reflectionSetter = ReflectionHelpers.GetFieldSetter<TestClass, int>(field);
481
+ }
482
+
483
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
484
+ Assert.That(
485
+ ReflectionHelpers.TryGetDelegateStrategy(expressionSetter, out expressionStrategy),
486
+ Is.True
487
+ );
488
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
489
+ Assert.That(
490
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
491
+ Is.True
492
+ );
493
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
494
+ Assert.That(
495
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionSetter, out reflectionStrategy),
496
+ Is.True
497
+ );
498
+
499
+ Assume.That(
500
+ expressionStrategy,
501
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
502
+ "Expression delegates are unavailable on this platform."
503
+ );
504
+ Assume.That(
505
+ dynamicStrategy,
506
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
507
+ "Dynamic IL delegates are unavailable on this platform."
508
+ );
509
+ Assert.That(
510
+ reflectionStrategy,
511
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
512
+ );
513
+
514
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
515
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
516
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
517
+
518
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
519
+ {
520
+ FieldSetter<TestClass, int> expressionSetterSecond =
521
+ ReflectionHelpers.GetFieldSetter<TestClass, int>(field);
522
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
523
+ }
524
+
525
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
526
+ {
527
+ FieldSetter<TestClass, int> dynamicSetterSecond = ReflectionHelpers.GetFieldSetter<
528
+ TestClass,
529
+ int
530
+ >(field);
531
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
532
+ }
533
+
534
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
535
+ {
536
+ FieldSetter<TestClass, int> reflectionSetterSecond =
537
+ ReflectionHelpers.GetFieldSetter<TestClass, int>(field);
538
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
539
+ }
540
+ }
541
+
542
+ [Test]
543
+ public void StaticFieldGetterCachesRemainStrategyScoped()
544
+ {
545
+ FieldInfo field = typeof(TestClass).GetField(
546
+ nameof(TestClass.StaticIntValue),
547
+ BindingFlags.Static | BindingFlags.Public
548
+ );
549
+ int original = TestClass.StaticIntValue;
550
+ try
551
+ {
552
+ TestClass.StaticIntValue = 111;
553
+ Func<object> expressionGetter;
554
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
555
+ {
556
+ expressionGetter = ReflectionHelpers.GetStaticFieldGetter(field);
557
+ }
558
+
559
+ Func<object> dynamicGetter;
560
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
561
+ {
562
+ dynamicGetter = ReflectionHelpers.GetStaticFieldGetter(field);
563
+ }
564
+
565
+ Func<object> reflectionGetter;
566
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
567
+ {
568
+ reflectionGetter = ReflectionHelpers.GetStaticFieldGetter(field);
569
+ }
570
+
571
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
572
+ Assert.That(
573
+ ReflectionHelpers.TryGetDelegateStrategy(
574
+ expressionGetter,
575
+ out expressionStrategy
576
+ ),
577
+ Is.True
578
+ );
579
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
580
+ Assert.That(
581
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
582
+ Is.True
583
+ );
584
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
585
+ Assert.That(
586
+ ReflectionHelpers.TryGetDelegateStrategy(
587
+ reflectionGetter,
588
+ out reflectionStrategy
589
+ ),
590
+ Is.True
591
+ );
592
+
593
+ Assume.That(
594
+ expressionStrategy,
595
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
596
+ "Expression delegates are unavailable on this platform."
597
+ );
598
+ Assume.That(
599
+ dynamicStrategy,
600
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
601
+ "Dynamic IL delegates are unavailable on this platform."
602
+ );
603
+ Assert.That(
604
+ reflectionStrategy,
605
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
606
+ );
607
+
608
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
609
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
610
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
611
+
612
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
613
+ {
614
+ Func<object> expressionGetterSecond = ReflectionHelpers.GetStaticFieldGetter(
615
+ field
616
+ );
617
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
618
+ }
619
+
620
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
621
+ {
622
+ Func<object> dynamicGetterSecond = ReflectionHelpers.GetStaticFieldGetter(
623
+ field
624
+ );
625
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
626
+ }
627
+
628
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
629
+ {
630
+ Func<object> reflectionGetterSecond = ReflectionHelpers.GetStaticFieldGetter(
631
+ field
632
+ );
633
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
634
+ }
635
+ }
636
+ finally
637
+ {
638
+ TestClass.StaticIntValue = original;
639
+ }
640
+ }
641
+
642
+ [Test]
643
+ public void StaticFieldSetterCachesRemainStrategyScoped()
644
+ {
645
+ FieldInfo field = typeof(TestClass).GetField(
646
+ nameof(TestClass.StaticIntValue),
647
+ BindingFlags.Static | BindingFlags.Public
648
+ );
649
+ int original = TestClass.StaticIntValue;
650
+ try
651
+ {
652
+ Action<object> expressionSetter;
653
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
654
+ {
655
+ expressionSetter = ReflectionHelpers.GetStaticFieldSetter(field);
656
+ }
657
+
658
+ Action<object> dynamicSetter;
659
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
660
+ {
661
+ dynamicSetter = ReflectionHelpers.GetStaticFieldSetter(field);
662
+ }
663
+
664
+ Action<object> reflectionSetter;
665
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
666
+ {
667
+ reflectionSetter = ReflectionHelpers.GetStaticFieldSetter(field);
668
+ }
669
+
670
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
671
+ Assert.That(
672
+ ReflectionHelpers.TryGetDelegateStrategy(
673
+ expressionSetter,
674
+ out expressionStrategy
675
+ ),
676
+ Is.True
677
+ );
678
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
679
+ Assert.That(
680
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
681
+ Is.True
682
+ );
683
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
684
+ Assert.That(
685
+ ReflectionHelpers.TryGetDelegateStrategy(
686
+ reflectionSetter,
687
+ out reflectionStrategy
688
+ ),
689
+ Is.True
690
+ );
691
+
692
+ Assume.That(
693
+ expressionStrategy,
694
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
695
+ "Expression delegates are unavailable on this platform."
696
+ );
697
+ Assume.That(
698
+ dynamicStrategy,
699
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
700
+ "Dynamic IL delegates are unavailable on this platform."
701
+ );
702
+ Assert.That(
703
+ reflectionStrategy,
704
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
705
+ );
706
+
707
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
708
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
709
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
710
+
711
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
712
+ {
713
+ Action<object> expressionSetterSecond = ReflectionHelpers.GetStaticFieldSetter(
714
+ field
715
+ );
716
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
717
+ }
718
+
719
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
720
+ {
721
+ Action<object> dynamicSetterSecond = ReflectionHelpers.GetStaticFieldSetter(
722
+ field
723
+ );
724
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
725
+ }
726
+
727
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
728
+ {
729
+ Action<object> reflectionSetterSecond = ReflectionHelpers.GetStaticFieldSetter(
730
+ field
731
+ );
732
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
733
+ }
734
+ }
735
+ finally
736
+ {
737
+ TestClass.StaticIntValue = original;
738
+ }
739
+ }
740
+
741
+ [Test]
742
+ public void StaticFieldGetterTypedCachesRemainStrategyScoped()
743
+ {
744
+ FieldInfo field = typeof(TestClass).GetField(
745
+ nameof(TestClass.StaticIntValue),
746
+ BindingFlags.Static | BindingFlags.Public
747
+ );
748
+ int original = TestClass.StaticIntValue;
749
+ try
750
+ {
751
+ TestClass.StaticIntValue = 314;
752
+ Func<int> expressionGetter;
753
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
754
+ {
755
+ expressionGetter = ReflectionHelpers.GetStaticFieldGetter<int>(field);
756
+ }
757
+
758
+ Func<int> dynamicGetter;
759
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
760
+ {
761
+ dynamicGetter = ReflectionHelpers.GetStaticFieldGetter<int>(field);
762
+ }
763
+
764
+ Func<int> reflectionGetter;
765
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
766
+ {
767
+ reflectionGetter = ReflectionHelpers.GetStaticFieldGetter<int>(field);
768
+ }
769
+
770
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
771
+ Assert.That(
772
+ ReflectionHelpers.TryGetDelegateStrategy(
773
+ expressionGetter,
774
+ out expressionStrategy
775
+ ),
776
+ Is.True
777
+ );
778
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
779
+ Assert.That(
780
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
781
+ Is.True
782
+ );
783
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
784
+ Assert.That(
785
+ ReflectionHelpers.TryGetDelegateStrategy(
786
+ reflectionGetter,
787
+ out reflectionStrategy
788
+ ),
789
+ Is.True
790
+ );
791
+
792
+ Assume.That(
793
+ expressionStrategy,
794
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
795
+ "Expression delegates are unavailable on this platform."
796
+ );
797
+ Assume.That(
798
+ dynamicStrategy,
799
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
800
+ "Dynamic IL delegates are unavailable on this platform."
801
+ );
802
+ Assert.That(
803
+ reflectionStrategy,
804
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
805
+ );
806
+
807
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
808
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
809
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
810
+
811
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
812
+ {
813
+ Func<int> expressionGetterSecond = ReflectionHelpers.GetStaticFieldGetter<int>(
814
+ field
815
+ );
816
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
817
+ }
818
+
819
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
820
+ {
821
+ Func<int> dynamicGetterSecond = ReflectionHelpers.GetStaticFieldGetter<int>(
822
+ field
823
+ );
824
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
825
+ }
826
+
827
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
828
+ {
829
+ Func<int> reflectionGetterSecond = ReflectionHelpers.GetStaticFieldGetter<int>(
830
+ field
831
+ );
832
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
833
+ }
834
+ }
835
+ finally
836
+ {
837
+ TestClass.StaticIntValue = original;
838
+ }
839
+ }
840
+
841
+ [Test]
842
+ public void StaticFieldSetterTypedCachesRemainStrategyScoped()
843
+ {
844
+ FieldInfo field = typeof(TestClass).GetField(
845
+ nameof(TestClass.StaticIntValue),
846
+ BindingFlags.Static | BindingFlags.Public
847
+ );
848
+ int original = TestClass.StaticIntValue;
849
+ try
850
+ {
851
+ Action<int> expressionSetter;
852
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
853
+ {
854
+ expressionSetter = ReflectionHelpers.GetStaticFieldSetter<int>(field);
855
+ }
856
+
857
+ Action<int> dynamicSetter;
858
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
859
+ {
860
+ dynamicSetter = ReflectionHelpers.GetStaticFieldSetter<int>(field);
861
+ }
862
+
863
+ Action<int> reflectionSetter;
864
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
865
+ {
866
+ reflectionSetter = ReflectionHelpers.GetStaticFieldSetter<int>(field);
867
+ }
868
+
869
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
870
+ Assert.That(
871
+ ReflectionHelpers.TryGetDelegateStrategy(
872
+ expressionSetter,
873
+ out expressionStrategy
874
+ ),
875
+ Is.True
876
+ );
877
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
878
+ Assert.That(
879
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
880
+ Is.True
881
+ );
882
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
883
+ Assert.That(
884
+ ReflectionHelpers.TryGetDelegateStrategy(
885
+ reflectionSetter,
886
+ out reflectionStrategy
887
+ ),
888
+ Is.True
889
+ );
890
+
891
+ Assume.That(
892
+ expressionStrategy,
893
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
894
+ "Expression delegates are unavailable on this platform."
895
+ );
896
+ Assume.That(
897
+ dynamicStrategy,
898
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
899
+ "Dynamic IL delegates are unavailable on this platform."
900
+ );
901
+ Assert.That(
902
+ reflectionStrategy,
903
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
904
+ );
905
+
906
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
907
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
908
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
909
+
910
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
911
+ {
912
+ Action<int> expressionSetterSecond =
913
+ ReflectionHelpers.GetStaticFieldSetter<int>(field);
914
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
915
+ }
916
+
917
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
918
+ {
919
+ Action<int> dynamicSetterSecond = ReflectionHelpers.GetStaticFieldSetter<int>(
920
+ field
921
+ );
922
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
923
+ }
924
+
925
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
926
+ {
927
+ Action<int> reflectionSetterSecond =
928
+ ReflectionHelpers.GetStaticFieldSetter<int>(field);
929
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
930
+ }
931
+ }
932
+ finally
933
+ {
934
+ TestClass.StaticIntValue = original;
935
+ }
936
+ }
937
+
938
+ [TestCaseSource(nameof(CapabilityModes))]
939
+ public void PropertyGetterBoxedSupportsCapabilities(CapabilityMode mode)
940
+ {
941
+ RunInCapabilityMode(
942
+ mode,
943
+ () =>
944
+ {
945
+ VariantPropertyClass instance = new() { ObjectProperty = "value" };
946
+ PropertyInfo property = typeof(VariantPropertyClass).GetProperty(
947
+ nameof(VariantPropertyClass.ObjectProperty)
948
+ );
949
+ Func<object, object> getter = ReflectionHelpers.GetPropertyGetter(property);
950
+ Assert.AreEqual("value", getter(instance));
951
+ }
952
+ );
953
+ }
954
+
955
+ [TestCaseSource(nameof(CapabilityModes))]
956
+ public void PropertySetterBoxedSupportsCapabilities(CapabilityMode mode)
957
+ {
958
+ RunInCapabilityMode(
959
+ mode,
960
+ () =>
961
+ {
962
+ VariantPropertyClass instance = new();
963
+ PropertyInfo property = typeof(VariantPropertyClass).GetProperty(
964
+ nameof(VariantPropertyClass.ObjectProperty)
965
+ );
966
+ Action<object, object> setter = ReflectionHelpers.GetPropertySetter(property);
967
+ setter(instance, "assigned");
968
+ Assert.AreEqual("assigned", instance.ObjectProperty);
969
+ }
970
+ );
971
+ }
972
+
973
+ [TestCaseSource(nameof(CapabilityModes))]
974
+ public void PropertyGetterTypedSupportsCapabilities(CapabilityMode mode)
975
+ {
976
+ RunInCapabilityMode(
977
+ mode,
978
+ () =>
979
+ {
980
+ TestPropertyClass instance = new() { InstanceProperty = 18 };
981
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
982
+ nameof(TestPropertyClass.InstanceProperty)
983
+ );
984
+ Func<TestPropertyClass, int> getter = ReflectionHelpers.GetPropertyGetter<
985
+ TestPropertyClass,
986
+ int
987
+ >(property);
988
+ Assert.AreEqual(18, getter(instance));
989
+ }
990
+ );
991
+ }
992
+
993
+ [Test]
994
+ public void PropertyGetterCachesRemainStrategyScoped()
995
+ {
996
+ VariantPropertyClass instance = new() { ObjectProperty = "first" };
997
+ PropertyInfo property = typeof(VariantPropertyClass).GetProperty(
998
+ nameof(VariantPropertyClass.ObjectProperty)
999
+ );
1000
+ Func<object, object> expressionGetter;
1001
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1002
+ {
1003
+ expressionGetter = ReflectionHelpers.GetPropertyGetter(property);
1004
+ }
1005
+
1006
+ Func<object, object> dynamicGetter;
1007
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1008
+ {
1009
+ dynamicGetter = ReflectionHelpers.GetPropertyGetter(property);
1010
+ }
1011
+
1012
+ Func<object, object> reflectionGetter;
1013
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1014
+ {
1015
+ reflectionGetter = ReflectionHelpers.GetPropertyGetter(property);
1016
+ }
1017
+
1018
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1019
+ Assert.That(
1020
+ ReflectionHelpers.TryGetDelegateStrategy(expressionGetter, out expressionStrategy),
1021
+ Is.True
1022
+ );
1023
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1024
+ Assert.That(
1025
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
1026
+ Is.True
1027
+ );
1028
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1029
+ Assert.That(
1030
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionGetter, out reflectionStrategy),
1031
+ Is.True
1032
+ );
1033
+
1034
+ Assume.That(
1035
+ expressionStrategy,
1036
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1037
+ "Expression delegates are unavailable on this platform."
1038
+ );
1039
+ Assume.That(
1040
+ dynamicStrategy,
1041
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1042
+ "Dynamic IL delegates are unavailable on this platform."
1043
+ );
1044
+ Assert.That(
1045
+ reflectionStrategy,
1046
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1047
+ );
1048
+
1049
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
1050
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
1051
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
1052
+
1053
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1054
+ {
1055
+ Func<object, object> expressionGetterSecond = ReflectionHelpers.GetPropertyGetter(
1056
+ property
1057
+ );
1058
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
1059
+ }
1060
+
1061
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1062
+ {
1063
+ Func<object, object> dynamicGetterSecond = ReflectionHelpers.GetPropertyGetter(
1064
+ property
1065
+ );
1066
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
1067
+ }
1068
+
1069
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1070
+ {
1071
+ Func<object, object> reflectionGetterSecond = ReflectionHelpers.GetPropertyGetter(
1072
+ property
1073
+ );
1074
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
1075
+ }
1076
+ }
1077
+
1078
+ [Test]
1079
+ public void PropertySetterCachesRemainStrategyScoped()
1080
+ {
1081
+ VariantPropertyClass instance = new();
1082
+ PropertyInfo property = typeof(VariantPropertyClass).GetProperty(
1083
+ nameof(VariantPropertyClass.ObjectProperty)
1084
+ );
1085
+ Action<object, object> expressionSetter;
1086
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1087
+ {
1088
+ expressionSetter = ReflectionHelpers.GetPropertySetter(property);
1089
+ }
1090
+
1091
+ Action<object, object> dynamicSetter;
1092
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1093
+ {
1094
+ dynamicSetter = ReflectionHelpers.GetPropertySetter(property);
1095
+ }
1096
+
1097
+ Action<object, object> reflectionSetter;
1098
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1099
+ {
1100
+ reflectionSetter = ReflectionHelpers.GetPropertySetter(property);
1101
+ }
1102
+
1103
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1104
+ Assert.That(
1105
+ ReflectionHelpers.TryGetDelegateStrategy(expressionSetter, out expressionStrategy),
1106
+ Is.True
1107
+ );
1108
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1109
+ Assert.That(
1110
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
1111
+ Is.True
1112
+ );
1113
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1114
+ Assert.That(
1115
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionSetter, out reflectionStrategy),
1116
+ Is.True
1117
+ );
1118
+
1119
+ Assume.That(
1120
+ expressionStrategy,
1121
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1122
+ "Expression delegates are unavailable on this platform."
1123
+ );
1124
+ Assume.That(
1125
+ dynamicStrategy,
1126
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1127
+ "Dynamic IL delegates are unavailable on this platform."
1128
+ );
1129
+ Assert.That(
1130
+ reflectionStrategy,
1131
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1132
+ );
1133
+
1134
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
1135
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
1136
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
1137
+
1138
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1139
+ {
1140
+ Action<object, object> expressionSetterSecond = ReflectionHelpers.GetPropertySetter(
1141
+ property
1142
+ );
1143
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
1144
+ }
1145
+
1146
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1147
+ {
1148
+ Action<object, object> dynamicSetterSecond = ReflectionHelpers.GetPropertySetter(
1149
+ property
1150
+ );
1151
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
1152
+ }
1153
+
1154
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1155
+ {
1156
+ Action<object, object> reflectionSetterSecond = ReflectionHelpers.GetPropertySetter(
1157
+ property
1158
+ );
1159
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
1160
+ }
1161
+
1162
+ expressionSetter(instance, "expr");
1163
+ dynamicSetter(instance, "dyn");
1164
+ reflectionSetter(instance, "ref");
1165
+ Assert.That(instance.ObjectProperty, Is.EqualTo("ref"));
1166
+ }
1167
+
1168
+ [Test]
1169
+ public void IndexerGetterCachesRemainStrategyScoped()
1170
+ {
1171
+ IndexerClass instance = new();
1172
+ instance[3] = 42;
1173
+ PropertyInfo indexer = typeof(IndexerClass).GetProperty("Item");
1174
+ Func<object, object[], object> expressionGetter;
1175
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1176
+ {
1177
+ expressionGetter = ReflectionHelpers.GetIndexerGetter(indexer);
1178
+ }
1179
+
1180
+ Func<object, object[], object> dynamicGetter;
1181
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1182
+ {
1183
+ dynamicGetter = ReflectionHelpers.GetIndexerGetter(indexer);
1184
+ }
1185
+
1186
+ Func<object, object[], object> reflectionGetter;
1187
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1188
+ {
1189
+ reflectionGetter = ReflectionHelpers.GetIndexerGetter(indexer);
1190
+ }
1191
+
1192
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1193
+ Assert.That(
1194
+ ReflectionHelpers.TryGetDelegateStrategy(expressionGetter, out expressionStrategy),
1195
+ Is.True
1196
+ );
1197
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1198
+ Assert.That(
1199
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicGetter, out dynamicStrategy),
1200
+ Is.True
1201
+ );
1202
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1203
+ Assert.That(
1204
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionGetter, out reflectionStrategy),
1205
+ Is.True
1206
+ );
1207
+
1208
+ Assume.That(
1209
+ expressionStrategy,
1210
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1211
+ "Expression delegates are unavailable on this platform."
1212
+ );
1213
+ Assume.That(
1214
+ dynamicStrategy,
1215
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1216
+ "Dynamic IL delegates are unavailable on this platform."
1217
+ );
1218
+ Assert.That(
1219
+ reflectionStrategy,
1220
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1221
+ );
1222
+
1223
+ Assert.That(expressionGetter, Is.Not.SameAs(dynamicGetter));
1224
+ Assert.That(expressionGetter, Is.Not.SameAs(reflectionGetter));
1225
+ Assert.That(dynamicGetter, Is.Not.SameAs(reflectionGetter));
1226
+
1227
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1228
+ {
1229
+ Func<object, object[], object> expressionGetterSecond =
1230
+ ReflectionHelpers.GetIndexerGetter(indexer);
1231
+ Assert.That(expressionGetterSecond, Is.SameAs(expressionGetter));
1232
+ }
1233
+
1234
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1235
+ {
1236
+ Func<object, object[], object> dynamicGetterSecond =
1237
+ ReflectionHelpers.GetIndexerGetter(indexer);
1238
+ Assert.That(dynamicGetterSecond, Is.SameAs(dynamicGetter));
1239
+ }
1240
+
1241
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1242
+ {
1243
+ Func<object, object[], object> reflectionGetterSecond =
1244
+ ReflectionHelpers.GetIndexerGetter(indexer);
1245
+ Assert.That(reflectionGetterSecond, Is.SameAs(reflectionGetter));
1246
+ }
1247
+
1248
+ Assert.That(expressionGetter(instance, new object[] { 3 }), Is.EqualTo(42));
1249
+ Assert.That(dynamicGetter(instance, new object[] { 3 }), Is.EqualTo(42));
1250
+ Assert.That(reflectionGetter(instance, new object[] { 3 }), Is.EqualTo(42));
1251
+ }
1252
+
1253
+ [Test]
1254
+ public void IndexerSetterCachesRemainStrategyScoped()
1255
+ {
1256
+ IndexerClass instance = new();
1257
+ PropertyInfo indexer = typeof(IndexerClass).GetProperty("Item");
1258
+ Action<object, object, object[]> expressionSetter;
1259
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1260
+ {
1261
+ expressionSetter = ReflectionHelpers.GetIndexerSetter(indexer);
1262
+ }
1263
+
1264
+ Action<object, object, object[]> dynamicSetter;
1265
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1266
+ {
1267
+ dynamicSetter = ReflectionHelpers.GetIndexerSetter(indexer);
1268
+ }
1269
+
1270
+ Action<object, object, object[]> reflectionSetter;
1271
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1272
+ {
1273
+ reflectionSetter = ReflectionHelpers.GetIndexerSetter(indexer);
1274
+ }
1275
+
1276
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1277
+ Assert.That(
1278
+ ReflectionHelpers.TryGetDelegateStrategy(expressionSetter, out expressionStrategy),
1279
+ Is.True
1280
+ );
1281
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1282
+ Assert.That(
1283
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicSetter, out dynamicStrategy),
1284
+ Is.True
1285
+ );
1286
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1287
+ Assert.That(
1288
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionSetter, out reflectionStrategy),
1289
+ Is.True
1290
+ );
1291
+
1292
+ Assume.That(
1293
+ expressionStrategy,
1294
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1295
+ "Expression delegates are unavailable on this platform."
1296
+ );
1297
+ Assume.That(
1298
+ dynamicStrategy,
1299
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1300
+ "Dynamic IL delegates are unavailable on this platform."
1301
+ );
1302
+ Assert.That(
1303
+ reflectionStrategy,
1304
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1305
+ );
1306
+
1307
+ Assert.That(expressionSetter, Is.Not.SameAs(dynamicSetter));
1308
+ Assert.That(expressionSetter, Is.Not.SameAs(reflectionSetter));
1309
+ Assert.That(dynamicSetter, Is.Not.SameAs(reflectionSetter));
1310
+
1311
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1312
+ {
1313
+ Action<object, object, object[]> expressionSetterSecond =
1314
+ ReflectionHelpers.GetIndexerSetter(indexer);
1315
+ Assert.That(expressionSetterSecond, Is.SameAs(expressionSetter));
1316
+ }
1317
+
1318
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1319
+ {
1320
+ Action<object, object, object[]> dynamicSetterSecond =
1321
+ ReflectionHelpers.GetIndexerSetter(indexer);
1322
+ Assert.That(dynamicSetterSecond, Is.SameAs(dynamicSetter));
1323
+ }
1324
+
1325
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1326
+ {
1327
+ Action<object, object, object[]> reflectionSetterSecond =
1328
+ ReflectionHelpers.GetIndexerSetter(indexer);
1329
+ Assert.That(reflectionSetterSecond, Is.SameAs(reflectionSetter));
1330
+ }
1331
+
1332
+ expressionSetter(instance, 100, new object[] { 1 });
1333
+ dynamicSetter(instance, 200, new object[] { 2 });
1334
+ reflectionSetter(instance, 300, new object[] { 3 });
1335
+ Assert.That(instance[1], Is.EqualTo(100));
1336
+ Assert.That(instance[2], Is.EqualTo(200));
1337
+ Assert.That(instance[3], Is.EqualTo(300));
1338
+ }
1339
+
1340
+ [Test]
1341
+ public void ConstructorInvokerCachesRemainStrategyScoped()
1342
+ {
1343
+ ConstructorInfo ctor = typeof(TestConstructorClass).GetConstructor(
1344
+ new[] { typeof(int), typeof(string), typeof(bool) }
1345
+ );
1346
+ Func<object[], object> expressionInvoker;
1347
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1348
+ {
1349
+ expressionInvoker = ReflectionHelpers.GetConstructor(ctor);
1350
+ }
1351
+
1352
+ Func<object[], object> dynamicInvoker;
1353
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1354
+ {
1355
+ dynamicInvoker = ReflectionHelpers.GetConstructor(ctor);
1356
+ }
1357
+
1358
+ Func<object[], object> reflectionInvoker;
1359
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1360
+ {
1361
+ reflectionInvoker = ReflectionHelpers.GetConstructor(ctor);
1362
+ }
1363
+
1364
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1365
+ Assert.That(
1366
+ ReflectionHelpers.TryGetDelegateStrategy(expressionInvoker, out expressionStrategy),
1367
+ Is.True
1368
+ );
1369
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1370
+ Assert.That(
1371
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicInvoker, out dynamicStrategy),
1372
+ Is.True
1373
+ );
1374
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1375
+ Assert.That(
1376
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionInvoker, out reflectionStrategy),
1377
+ Is.True
1378
+ );
1379
+
1380
+ Assume.That(
1381
+ expressionStrategy,
1382
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1383
+ "Expression delegates are unavailable on this platform."
1384
+ );
1385
+ Assume.That(
1386
+ dynamicStrategy,
1387
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1388
+ "Dynamic IL delegates are unavailable on this platform."
1389
+ );
1390
+ Assert.That(
1391
+ reflectionStrategy,
1392
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1393
+ );
1394
+
1395
+ Assert.That(expressionInvoker, Is.Not.SameAs(dynamicInvoker));
1396
+ Assert.That(expressionInvoker, Is.Not.SameAs(reflectionInvoker));
1397
+ Assert.That(dynamicInvoker, Is.Not.SameAs(reflectionInvoker));
1398
+
1399
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1400
+ {
1401
+ Func<object[], object> expressionInvokerSecond = ReflectionHelpers.GetConstructor(
1402
+ ctor
1403
+ );
1404
+ Assert.That(expressionInvokerSecond, Is.SameAs(expressionInvoker));
1405
+ }
1406
+
1407
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1408
+ {
1409
+ Func<object[], object> dynamicInvokerSecond = ReflectionHelpers.GetConstructor(
1410
+ ctor
1411
+ );
1412
+ Assert.That(dynamicInvokerSecond, Is.SameAs(dynamicInvoker));
1413
+ }
1414
+
1415
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1416
+ {
1417
+ Func<object[], object> reflectionInvokerSecond = ReflectionHelpers.GetConstructor(
1418
+ ctor
1419
+ );
1420
+ Assert.That(reflectionInvokerSecond, Is.SameAs(reflectionInvoker));
1421
+ }
1422
+
1423
+ object expressionInstance = expressionInvoker(new object[] { 1, "expr", true });
1424
+ object dynamicInstance = dynamicInvoker(new object[] { 2, "dyn", false });
1425
+ object reflectionInstance = reflectionInvoker(new object[] { 3, "ref", true });
1426
+ Assert.AreEqual("expr", ((TestConstructorClass)expressionInstance).Value2);
1427
+ Assert.AreEqual("dyn", ((TestConstructorClass)dynamicInstance).Value2);
1428
+ Assert.AreEqual("ref", ((TestConstructorClass)reflectionInstance).Value2);
1429
+ }
1430
+
1431
+ [Test]
1432
+ public void ParameterlessConstructorCachesRemainStrategyScoped()
1433
+ {
1434
+ Func<object> expressionCreator;
1435
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1436
+ {
1437
+ expressionCreator = ReflectionHelpers.GetParameterlessConstructor(
1438
+ typeof(TestConstructorClass)
1439
+ );
1440
+ }
1441
+
1442
+ Func<object> dynamicCreator;
1443
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1444
+ {
1445
+ dynamicCreator = ReflectionHelpers.GetParameterlessConstructor(
1446
+ typeof(TestConstructorClass)
1447
+ );
1448
+ }
1449
+
1450
+ Func<object> reflectionCreator;
1451
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1452
+ {
1453
+ reflectionCreator = ReflectionHelpers.GetParameterlessConstructor(
1454
+ typeof(TestConstructorClass)
1455
+ );
1456
+ }
1457
+
1458
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1459
+ Assert.That(
1460
+ ReflectionHelpers.TryGetDelegateStrategy(expressionCreator, out expressionStrategy),
1461
+ Is.True
1462
+ );
1463
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1464
+ Assert.That(
1465
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicCreator, out dynamicStrategy),
1466
+ Is.True
1467
+ );
1468
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1469
+ Assert.That(
1470
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionCreator, out reflectionStrategy),
1471
+ Is.True
1472
+ );
1473
+
1474
+ Assume.That(
1475
+ expressionStrategy,
1476
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1477
+ "Expression delegates are unavailable on this platform."
1478
+ );
1479
+ Assume.That(
1480
+ dynamicStrategy,
1481
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1482
+ "Dynamic IL delegates are unavailable on this platform."
1483
+ );
1484
+ Assert.That(
1485
+ reflectionStrategy,
1486
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1487
+ );
1488
+
1489
+ Assert.That(expressionCreator, Is.Not.SameAs(dynamicCreator));
1490
+ Assert.That(expressionCreator, Is.Not.SameAs(reflectionCreator));
1491
+ Assert.That(dynamicCreator, Is.Not.SameAs(reflectionCreator));
1492
+
1493
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1494
+ {
1495
+ Func<object> expressionCreatorSecond =
1496
+ ReflectionHelpers.GetParameterlessConstructor(typeof(TestConstructorClass));
1497
+ Assert.That(expressionCreatorSecond, Is.SameAs(expressionCreator));
1498
+ }
1499
+
1500
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1501
+ {
1502
+ Func<object> dynamicCreatorSecond = ReflectionHelpers.GetParameterlessConstructor(
1503
+ typeof(TestConstructorClass)
1504
+ );
1505
+ Assert.That(dynamicCreatorSecond, Is.SameAs(dynamicCreator));
1506
+ }
1507
+
1508
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1509
+ {
1510
+ Func<object> reflectionCreatorSecond =
1511
+ ReflectionHelpers.GetParameterlessConstructor(typeof(TestConstructorClass));
1512
+ Assert.That(reflectionCreatorSecond, Is.SameAs(reflectionCreator));
1513
+ }
1514
+
1515
+ Assert.IsInstanceOf<TestConstructorClass>(expressionCreator());
1516
+ Assert.IsInstanceOf<TestConstructorClass>(dynamicCreator());
1517
+ Assert.IsInstanceOf<TestConstructorClass>(reflectionCreator());
1518
+ }
1519
+
1520
+ [Test]
1521
+ public void ParameterlessConstructorTypedCachesRemainStrategyScoped()
1522
+ {
1523
+ Func<TestConstructorClass> expressionCreator;
1524
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1525
+ {
1526
+ expressionCreator =
1527
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1528
+ }
1529
+
1530
+ Func<TestConstructorClass> dynamicCreator;
1531
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1532
+ {
1533
+ dynamicCreator =
1534
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1535
+ }
1536
+
1537
+ Func<TestConstructorClass> reflectionCreator;
1538
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1539
+ {
1540
+ reflectionCreator =
1541
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1542
+ }
1543
+
1544
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1545
+ Assert.That(
1546
+ ReflectionHelpers.TryGetDelegateStrategy(expressionCreator, out expressionStrategy),
1547
+ Is.True
1548
+ );
1549
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1550
+ Assert.That(
1551
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicCreator, out dynamicStrategy),
1552
+ Is.True
1553
+ );
1554
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1555
+ Assert.That(
1556
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionCreator, out reflectionStrategy),
1557
+ Is.True
1558
+ );
1559
+
1560
+ Assume.That(
1561
+ expressionStrategy,
1562
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1563
+ "Expression delegates are unavailable on this platform."
1564
+ );
1565
+ Assume.That(
1566
+ dynamicStrategy,
1567
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1568
+ "Dynamic IL delegates are unavailable on this platform."
1569
+ );
1570
+ Assert.That(
1571
+ reflectionStrategy,
1572
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1573
+ );
1574
+
1575
+ Assert.That(expressionCreator, Is.Not.SameAs(dynamicCreator));
1576
+ Assert.That(expressionCreator, Is.Not.SameAs(reflectionCreator));
1577
+ Assert.That(dynamicCreator, Is.Not.SameAs(reflectionCreator));
1578
+
1579
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1580
+ {
1581
+ Func<TestConstructorClass> expressionCreatorSecond =
1582
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1583
+ Assert.That(expressionCreatorSecond, Is.SameAs(expressionCreator));
1584
+ }
1585
+
1586
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1587
+ {
1588
+ Func<TestConstructorClass> dynamicCreatorSecond =
1589
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1590
+ Assert.That(dynamicCreatorSecond, Is.SameAs(dynamicCreator));
1591
+ }
1592
+
1593
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1594
+ {
1595
+ Func<TestConstructorClass> reflectionCreatorSecond =
1596
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
1597
+ Assert.That(reflectionCreatorSecond, Is.SameAs(reflectionCreator));
1598
+ }
1599
+
1600
+ Assert.AreEqual("default", expressionCreator().Value2);
1601
+ Assert.AreEqual("default", dynamicCreator().Value2);
1602
+ Assert.AreEqual("default", reflectionCreator().Value2);
1603
+ }
1604
+
1605
+ [Test]
1606
+ public void MethodInvokerCachesRemainStrategyScoped()
1607
+ {
1608
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
1609
+ nameof(TestMethodClass.InstanceMethodWithParam)
1610
+ );
1611
+ Func<object, object[], object> expressionInvoker;
1612
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1613
+ {
1614
+ expressionInvoker = ReflectionHelpers.GetMethodInvoker(method);
1615
+ }
1616
+
1617
+ Func<object, object[], object> dynamicInvoker;
1618
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1619
+ {
1620
+ dynamicInvoker = ReflectionHelpers.GetMethodInvoker(method);
1621
+ }
1622
+
1623
+ Func<object, object[], object> reflectionInvoker;
1624
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1625
+ {
1626
+ reflectionInvoker = ReflectionHelpers.GetMethodInvoker(method);
1627
+ }
1628
+
1629
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1630
+ Assert.That(
1631
+ ReflectionHelpers.TryGetDelegateStrategy(expressionInvoker, out expressionStrategy),
1632
+ Is.True
1633
+ );
1634
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1635
+ Assert.That(
1636
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicInvoker, out dynamicStrategy),
1637
+ Is.True
1638
+ );
1639
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1640
+ Assert.That(
1641
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionInvoker, out reflectionStrategy),
1642
+ Is.True
1643
+ );
1644
+
1645
+ Assume.That(
1646
+ expressionStrategy,
1647
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1648
+ "Expression delegates are unavailable on this platform."
1649
+ );
1650
+ Assume.That(
1651
+ dynamicStrategy,
1652
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1653
+ "Dynamic IL delegates are unavailable on this platform."
1654
+ );
1655
+ Assert.That(
1656
+ reflectionStrategy,
1657
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1658
+ );
1659
+
1660
+ Assert.That(expressionInvoker, Is.Not.SameAs(dynamicInvoker));
1661
+ Assert.That(expressionInvoker, Is.Not.SameAs(reflectionInvoker));
1662
+ Assert.That(dynamicInvoker, Is.Not.SameAs(reflectionInvoker));
1663
+
1664
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1665
+ {
1666
+ Func<object, object[], object> expressionInvokerSecond =
1667
+ ReflectionHelpers.GetMethodInvoker(method);
1668
+ Assert.That(expressionInvokerSecond, Is.SameAs(expressionInvoker));
1669
+ }
1670
+
1671
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1672
+ {
1673
+ Func<object, object[], object> dynamicInvokerSecond =
1674
+ ReflectionHelpers.GetMethodInvoker(method);
1675
+ Assert.That(dynamicInvokerSecond, Is.SameAs(dynamicInvoker));
1676
+ }
1677
+
1678
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1679
+ {
1680
+ Func<object, object[], object> reflectionInvokerSecond =
1681
+ ReflectionHelpers.GetMethodInvoker(method);
1682
+ Assert.That(reflectionInvokerSecond, Is.SameAs(reflectionInvoker));
1683
+ }
1684
+
1685
+ TestMethodClass instance = new();
1686
+ Assert.That(expressionInvoker(instance, new object[] { "abcd" }), Is.EqualTo(4));
1687
+ Assert.That(dynamicInvoker(instance, new object[] { "abcd" }), Is.EqualTo(4));
1688
+ Assert.That(reflectionInvoker(instance, new object[] { "abcd" }), Is.EqualTo(4));
1689
+ }
1690
+
1691
+ [Test]
1692
+ public void StaticMethodInvokerCachesRemainStrategyScoped()
1693
+ {
1694
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
1695
+ nameof(TestMethodClass.StaticMethodWithParam)
1696
+ );
1697
+ TestMethodClass.ResetStatic();
1698
+ Func<object[], object> expressionInvoker;
1699
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1700
+ {
1701
+ expressionInvoker = ReflectionHelpers.GetStaticMethodInvoker(method);
1702
+ }
1703
+
1704
+ Func<object[], object> dynamicInvoker;
1705
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1706
+ {
1707
+ dynamicInvoker = ReflectionHelpers.GetStaticMethodInvoker(method);
1708
+ }
1709
+
1710
+ Func<object[], object> reflectionInvoker;
1711
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1712
+ {
1713
+ reflectionInvoker = ReflectionHelpers.GetStaticMethodInvoker(method);
1714
+ }
1715
+
1716
+ ReflectionHelpers.ReflectionDelegateStrategy expressionStrategy;
1717
+ Assert.That(
1718
+ ReflectionHelpers.TryGetDelegateStrategy(expressionInvoker, out expressionStrategy),
1719
+ Is.True
1720
+ );
1721
+ ReflectionHelpers.ReflectionDelegateStrategy dynamicStrategy;
1722
+ Assert.That(
1723
+ ReflectionHelpers.TryGetDelegateStrategy(dynamicInvoker, out dynamicStrategy),
1724
+ Is.True
1725
+ );
1726
+ ReflectionHelpers.ReflectionDelegateStrategy reflectionStrategy;
1727
+ Assert.That(
1728
+ ReflectionHelpers.TryGetDelegateStrategy(reflectionInvoker, out reflectionStrategy),
1729
+ Is.True
1730
+ );
1731
+
1732
+ Assume.That(
1733
+ expressionStrategy,
1734
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1735
+ "Expression delegates are unavailable on this platform."
1736
+ );
1737
+ Assume.That(
1738
+ dynamicStrategy,
1739
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1740
+ "Dynamic IL delegates are unavailable on this platform."
1741
+ );
1742
+ Assert.That(
1743
+ reflectionStrategy,
1744
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1745
+ );
1746
+
1747
+ Assert.That(expressionInvoker, Is.Not.SameAs(dynamicInvoker));
1748
+ Assert.That(expressionInvoker, Is.Not.SameAs(reflectionInvoker));
1749
+ Assert.That(dynamicInvoker, Is.Not.SameAs(reflectionInvoker));
1750
+
1751
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1752
+ {
1753
+ Func<object[], object> expressionInvokerSecond =
1754
+ ReflectionHelpers.GetStaticMethodInvoker(method);
1755
+ Assert.That(expressionInvokerSecond, Is.SameAs(expressionInvoker));
1756
+ }
1757
+
1758
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1759
+ {
1760
+ Func<object[], object> dynamicInvokerSecond =
1761
+ ReflectionHelpers.GetStaticMethodInvoker(method);
1762
+ Assert.That(dynamicInvokerSecond, Is.SameAs(dynamicInvoker));
1763
+ }
1764
+
1765
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1766
+ {
1767
+ Func<object[], object> reflectionInvokerSecond =
1768
+ ReflectionHelpers.GetStaticMethodInvoker(method);
1769
+ Assert.That(reflectionInvokerSecond, Is.SameAs(reflectionInvoker));
1770
+ }
1771
+
1772
+ Assert.That(expressionInvoker(new object[] { 5 }), Is.EqualTo(10));
1773
+ Assert.That(dynamicInvoker(new object[] { 6 }), Is.EqualTo(12));
1774
+ Assert.That(reflectionInvoker(new object[] { 7 }), Is.EqualTo(14));
1775
+ }
1776
+
1777
+ [TestCaseSource(nameof(CapabilityModes))]
1778
+ public void PropertySetterTypedSupportsCapabilities(CapabilityMode mode)
1779
+ {
1780
+ RunInCapabilityMode(
1781
+ mode,
1782
+ () =>
1783
+ {
1784
+ TestPropertyClass instance = new();
1785
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1786
+ nameof(TestPropertyClass.InstanceProperty)
1787
+ );
1788
+ Action<TestPropertyClass, int> setter = ReflectionHelpers.GetPropertySetter<
1789
+ TestPropertyClass,
1790
+ int
1791
+ >(property);
1792
+ setter(instance, 27);
1793
+ Assert.AreEqual(27, instance.InstanceProperty);
1794
+ }
1795
+ );
1796
+ }
1797
+
1798
+ [TestCaseSource(nameof(CapabilityModes))]
1799
+ public void StaticPropertyGetterBoxedSupportsCapabilities(CapabilityMode mode)
1800
+ {
1801
+ int original = TestPropertyClass.StaticProperty;
1802
+ try
1803
+ {
1804
+ TestPropertyClass.StaticProperty = 64;
1805
+ RunInCapabilityMode(
1806
+ mode,
1807
+ () =>
1808
+ {
1809
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1810
+ nameof(TestPropertyClass.StaticProperty),
1811
+ BindingFlags.Static | BindingFlags.Public
1812
+ );
1813
+ Func<object, object> getter = ReflectionHelpers.GetPropertyGetter(property);
1814
+ Assert.AreEqual(64, getter(null));
1815
+ }
1816
+ );
1817
+ }
1818
+ finally
1819
+ {
1820
+ TestPropertyClass.StaticProperty = original;
1821
+ }
1822
+ }
1823
+
1824
+ [Test]
1825
+ public void StaticPropertyGetterExpressionUsesCompiledDelegate()
1826
+ {
1827
+ int original = TestPropertyClass.StaticProperty;
1828
+ try
1829
+ {
1830
+ TestPropertyClass.StaticProperty = 123;
1831
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1832
+ nameof(TestPropertyClass.StaticProperty),
1833
+ BindingFlags.Static | BindingFlags.Public
1834
+ );
1835
+
1836
+ using (ReflectionHelpers.OverrideReflectionCapabilities(true, false))
1837
+ {
1838
+ Func<object, object> getter = ReflectionHelpers.GetPropertyGetter(property);
1839
+ ReflectionHelpers.ReflectionDelegateStrategy strategy;
1840
+ Assert.That(
1841
+ ReflectionHelpers.TryGetDelegateStrategy(getter, out strategy),
1842
+ Is.True
1843
+ );
1844
+ Assume.That(
1845
+ strategy,
1846
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Expressions),
1847
+ "Expression delegates are unavailable on this platform."
1848
+ );
1849
+
1850
+ Assert.AreEqual(123, getter(null));
1851
+ }
1852
+ }
1853
+ finally
1854
+ {
1855
+ TestPropertyClass.StaticProperty = original;
1856
+ }
1857
+ }
1858
+
1859
+ [Test]
1860
+ public void StaticPropertyGetterDynamicIlUsesEmittedDelegate()
1861
+ {
1862
+ if (!ReflectionHelpers.DynamicIlEnabled)
1863
+ {
1864
+ Assert.Ignore("Dynamic IL is not available on this platform.");
1865
+ }
1866
+
1867
+ int original = TestPropertyClass.StaticProperty;
1868
+ try
1869
+ {
1870
+ TestPropertyClass.StaticProperty = 234;
1871
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1872
+ nameof(TestPropertyClass.StaticProperty),
1873
+ BindingFlags.Static | BindingFlags.Public
1874
+ );
1875
+
1876
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, true))
1877
+ {
1878
+ Func<object, object> getter = ReflectionHelpers.GetPropertyGetter(property);
1879
+ ReflectionHelpers.ReflectionDelegateStrategy strategy;
1880
+ Assert.That(
1881
+ ReflectionHelpers.TryGetDelegateStrategy(getter, out strategy),
1882
+ Is.True
1883
+ );
1884
+ Assume.That(
1885
+ strategy,
1886
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.DynamicIl),
1887
+ "Dynamic IL delegates are unavailable on this platform."
1888
+ );
1889
+
1890
+ Assert.AreEqual(234, getter(null));
1891
+ }
1892
+ }
1893
+ finally
1894
+ {
1895
+ TestPropertyClass.StaticProperty = original;
1896
+ }
1897
+ }
1898
+
1899
+ [Test]
1900
+ public void StaticPropertyGetterReflectionUsesFallbackDelegate()
1901
+ {
1902
+ int original = TestPropertyClass.StaticProperty;
1903
+ try
1904
+ {
1905
+ TestPropertyClass.StaticProperty = 345;
1906
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1907
+ nameof(TestPropertyClass.StaticProperty),
1908
+ BindingFlags.Static | BindingFlags.Public
1909
+ );
1910
+
1911
+ using (ReflectionHelpers.OverrideReflectionCapabilities(false, false))
1912
+ {
1913
+ Func<object, object> getter = ReflectionHelpers.GetPropertyGetter(property);
1914
+ ReflectionHelpers.ReflectionDelegateStrategy strategy;
1915
+ Assert.That(
1916
+ ReflectionHelpers.TryGetDelegateStrategy(getter, out strategy),
1917
+ Is.True
1918
+ );
1919
+ Assert.That(
1920
+ strategy,
1921
+ Is.EqualTo(ReflectionHelpers.ReflectionDelegateStrategy.Reflection)
1922
+ );
1923
+
1924
+ Assert.AreEqual(345, getter(null));
1925
+ }
1926
+ }
1927
+ finally
1928
+ {
1929
+ TestPropertyClass.StaticProperty = original;
1930
+ }
1931
+ }
1932
+
1933
+ [TestCaseSource(nameof(CapabilityModes))]
1934
+ public void StaticPropertySetterBoxedSupportsCapabilities(CapabilityMode mode)
1935
+ {
1936
+ int original = TestPropertyClass.StaticProperty;
1937
+ try
1938
+ {
1939
+ RunInCapabilityMode(
1940
+ mode,
1941
+ () =>
1942
+ {
1943
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1944
+ nameof(TestPropertyClass.StaticProperty),
1945
+ BindingFlags.Static | BindingFlags.Public
1946
+ );
1947
+ Action<object, object> setter = ReflectionHelpers.GetPropertySetter(
1948
+ property
1949
+ );
1950
+ setter(null, 91);
1951
+ Assert.AreEqual(91, TestPropertyClass.StaticProperty);
1952
+ }
1953
+ );
1954
+ }
1955
+ finally
1956
+ {
1957
+ TestPropertyClass.StaticProperty = original;
1958
+ }
1959
+ }
1960
+
1961
+ [TestCaseSource(nameof(CapabilityModes))]
1962
+ public void StaticPropertyGetterTypedSupportsCapabilities(CapabilityMode mode)
1963
+ {
1964
+ int original = TestPropertyClass.StaticProperty;
1965
+ try
1966
+ {
1967
+ TestPropertyClass.StaticProperty = 333;
1968
+ RunInCapabilityMode(
1969
+ mode,
1970
+ () =>
1971
+ {
1972
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1973
+ nameof(TestPropertyClass.StaticProperty),
1974
+ BindingFlags.Static | BindingFlags.Public
1975
+ );
1976
+ Func<int> getter = ReflectionHelpers.GetStaticPropertyGetter<int>(property);
1977
+ Assert.AreEqual(333, getter());
1978
+ }
1979
+ );
1980
+ }
1981
+ finally
1982
+ {
1983
+ TestPropertyClass.StaticProperty = original;
1984
+ }
1985
+ }
1986
+
1987
+ [TestCaseSource(nameof(CapabilityModes))]
1988
+ public void StaticPropertySetterTypedSupportsCapabilities(CapabilityMode mode)
1989
+ {
1990
+ int original = TestPropertyClass.StaticProperty;
1991
+ try
1992
+ {
1993
+ RunInCapabilityMode(
1994
+ mode,
1995
+ () =>
1996
+ {
1997
+ PropertyInfo property = typeof(TestPropertyClass).GetProperty(
1998
+ nameof(TestPropertyClass.StaticProperty),
1999
+ BindingFlags.Static | BindingFlags.Public
2000
+ );
2001
+ Action<int> setter = ReflectionHelpers.GetStaticPropertySetter<int>(
2002
+ property
2003
+ );
2004
+ setter(444);
2005
+ Assert.AreEqual(444, TestPropertyClass.StaticProperty);
2006
+ }
2007
+ );
2008
+ }
2009
+ finally
2010
+ {
2011
+ TestPropertyClass.StaticProperty = original;
2012
+ }
2013
+ }
2014
+
2015
+ [TestCaseSource(nameof(CapabilityModes))]
2016
+ public void IndexerGetterSupportsCapabilities(CapabilityMode mode)
2017
+ {
2018
+ RunInCapabilityMode(
2019
+ mode,
2020
+ () =>
2021
+ {
2022
+ IndexerClass instance = new();
2023
+ instance[5] = 99;
2024
+ PropertyInfo indexer = typeof(IndexerClass).GetProperty("Item");
2025
+ Func<object, object[], object> getter = ReflectionHelpers.GetIndexerGetter(
2026
+ indexer
2027
+ );
2028
+ Assert.AreEqual(99, getter(instance, new object[] { 5 }));
2029
+ }
2030
+ );
2031
+ }
2032
+
2033
+ [TestCaseSource(nameof(CapabilityModes))]
2034
+ public void IndexerSetterSupportsCapabilities(CapabilityMode mode)
2035
+ {
2036
+ RunInCapabilityMode(
2037
+ mode,
2038
+ () =>
2039
+ {
2040
+ IndexerClass instance = new();
2041
+ PropertyInfo indexer = typeof(IndexerClass).GetProperty("Item");
2042
+ Action<object, object, object[]> setter = ReflectionHelpers.GetIndexerSetter(
2043
+ indexer
2044
+ );
2045
+ setter(instance, 111, new object[] { 7 });
2046
+ Assert.AreEqual(111, instance[7]);
2047
+ }
2048
+ );
2049
+ }
2050
+
2051
+ [TestCaseSource(nameof(CapabilityModes))]
2052
+ public void MethodInvokerBoxedInstanceSupportsCapabilities(CapabilityMode mode)
2053
+ {
2054
+ RunInCapabilityMode(
2055
+ mode,
2056
+ () =>
2057
+ {
2058
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2059
+ nameof(TestMethodClass.InstanceMethodWithParam)
2060
+ );
2061
+ Func<object, object[], object> invoker = ReflectionHelpers.GetMethodInvoker(
2062
+ method
2063
+ );
2064
+ object result = invoker(new TestMethodClass(), new object[] { "abcd" });
2065
+ Assert.AreEqual(4, result);
2066
+ }
2067
+ );
2068
+ }
2069
+
2070
+ [TestCaseSource(nameof(CapabilityModes))]
2071
+ public void MethodInvokerBoxedStaticSupportsCapabilities(CapabilityMode mode)
2072
+ {
2073
+ TestMethodClass.ResetStatic();
2074
+ RunInCapabilityMode(
2075
+ mode,
2076
+ () =>
2077
+ {
2078
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2079
+ nameof(TestMethodClass.StaticMethodWithParam)
2080
+ );
2081
+ Func<object[], object> invoker = ReflectionHelpers.GetStaticMethodInvoker(
2082
+ method
2083
+ );
2084
+ object result = invoker(new object[] { 6 });
2085
+ Assert.AreEqual(12, result);
2086
+ }
2087
+ );
2088
+ }
2089
+
2090
+ [TestCaseSource(nameof(CapabilityModes))]
2091
+ public void MethodInvokerTypedInstanceNoArgsSupportsCapabilities(CapabilityMode mode)
2092
+ {
2093
+ RunInCapabilityMode(
2094
+ mode,
2095
+ () =>
2096
+ {
2097
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2098
+ nameof(TestMethodClass.InstanceIntMethod)
2099
+ );
2100
+ Func<TestMethodClass, int> invoker = ReflectionHelpers.GetInstanceMethodInvoker<
2101
+ TestMethodClass,
2102
+ int
2103
+ >(method);
2104
+ Assert.AreEqual(100, invoker(new TestMethodClass()));
2105
+ }
2106
+ );
2107
+ }
2108
+
2109
+ [TestCaseSource(nameof(CapabilityModes))]
2110
+ public void MethodInvokerTypedInstanceWithArgsSupportsCapabilities(CapabilityMode mode)
2111
+ {
2112
+ RunInCapabilityMode(
2113
+ mode,
2114
+ () =>
2115
+ {
2116
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2117
+ nameof(TestMethodClass.InstanceMethodWithParam)
2118
+ );
2119
+ Func<TestMethodClass, string, int> invoker =
2120
+ ReflectionHelpers.GetInstanceMethodInvoker<TestMethodClass, string, int>(
2121
+ method
2122
+ );
2123
+ Assert.AreEqual(3, invoker(new TestMethodClass(), "hey"));
2124
+ }
2125
+ );
2126
+ }
2127
+
2128
+ [TestCaseSource(nameof(CapabilityModes))]
2129
+ public void MethodInvokerTypedInstanceThreeArgsSupportsCapabilities(CapabilityMode mode)
2130
+ {
2131
+ RunInCapabilityMode(
2132
+ mode,
2133
+ () =>
2134
+ {
2135
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2136
+ nameof(TestMethodClass.InstanceMethodThreeParams)
2137
+ );
2138
+ Func<TestMethodClass, int, string, bool, int> invoker =
2139
+ ReflectionHelpers.GetInstanceMethodInvoker<
2140
+ TestMethodClass,
2141
+ int,
2142
+ string,
2143
+ bool,
2144
+ int
2145
+ >(method);
2146
+ int result = invoker(new TestMethodClass(), 2, "abc", true);
2147
+ Assert.AreEqual(2 + 3 + 1, result);
2148
+ }
2149
+ );
2150
+ }
2151
+
2152
+ [TestCaseSource(nameof(CapabilityModes))]
2153
+ public void MethodInvokerTypedInstanceFourArgsSupportsCapabilities(CapabilityMode mode)
2154
+ {
2155
+ RunInCapabilityMode(
2156
+ mode,
2157
+ () =>
2158
+ {
2159
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2160
+ nameof(TestMethodClass.InstanceSumFour)
2161
+ );
2162
+ Func<TestMethodClass, int, int, int, int, int> invoker =
2163
+ ReflectionHelpers.GetInstanceMethodInvoker<
2164
+ TestMethodClass,
2165
+ int,
2166
+ int,
2167
+ int,
2168
+ int,
2169
+ int
2170
+ >(method);
2171
+ int result = invoker(new TestMethodClass(), 1, 2, 3, 4);
2172
+ Assert.AreEqual(10, result);
2173
+ }
2174
+ );
2175
+ }
2176
+
2177
+ [TestCaseSource(nameof(CapabilityModes))]
2178
+ public void MethodInvokerTypedStaticNoArgsSupportsCapabilities(CapabilityMode mode)
2179
+ {
2180
+ TestMethodClass.ResetStatic();
2181
+ RunInCapabilityMode(
2182
+ mode,
2183
+ () =>
2184
+ {
2185
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2186
+ nameof(TestMethodClass.StaticIntMethod)
2187
+ );
2188
+ Func<int> invoker = ReflectionHelpers.GetStaticMethodInvoker<int>(method);
2189
+ Assert.AreEqual(42, invoker());
2190
+ }
2191
+ );
2192
+ }
2193
+
2194
+ [TestCaseSource(nameof(CapabilityModes))]
2195
+ public void MethodInvokerTypedStaticOneArgSupportsCapabilities(CapabilityMode mode)
2196
+ {
2197
+ TestMethodClass.ResetStatic();
2198
+ RunInCapabilityMode(
2199
+ mode,
2200
+ () =>
2201
+ {
2202
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2203
+ nameof(TestMethodClass.StaticMethodWithParam)
2204
+ );
2205
+ Func<int, int> invoker = ReflectionHelpers.GetStaticMethodInvoker<int, int>(
2206
+ method
2207
+ );
2208
+ Assert.AreEqual(20, invoker(10));
2209
+ }
2210
+ );
2211
+ }
2212
+
2213
+ [TestCaseSource(nameof(CapabilityModes))]
2214
+ public void MethodInvokerTypedStaticTwoArgsSupportsCapabilities(CapabilityMode mode)
2215
+ {
2216
+ TestMethodClass.ResetStatic();
2217
+ RunInCapabilityMode(
2218
+ mode,
2219
+ () =>
2220
+ {
2221
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2222
+ nameof(TestMethodClass.StaticMethodTwoParams)
2223
+ );
2224
+ Func<int, int, int> invoker = ReflectionHelpers.GetStaticMethodInvoker<
2225
+ int,
2226
+ int,
2227
+ int
2228
+ >(method);
2229
+ Assert.AreEqual(15, invoker(7, 8));
2230
+ }
2231
+ );
2232
+ }
2233
+
2234
+ [TestCaseSource(nameof(CapabilityModes))]
2235
+ public void MethodInvokerTypedStaticThreeArgsSupportsCapabilities(CapabilityMode mode)
2236
+ {
2237
+ TestMethodClass.ResetStatic();
2238
+ RunInCapabilityMode(
2239
+ mode,
2240
+ () =>
2241
+ {
2242
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2243
+ nameof(TestMethodClass.StaticMethodMultipleParams)
2244
+ );
2245
+ Func<int, string, bool, int> invoker = ReflectionHelpers.GetStaticMethodInvoker<
2246
+ int,
2247
+ string,
2248
+ bool,
2249
+ int
2250
+ >(method);
2251
+ Assert.AreEqual(5 + 4 + 1, invoker(5, "four", true));
2252
+ }
2253
+ );
2254
+ }
2255
+
2256
+ [TestCaseSource(nameof(CapabilityModes))]
2257
+ public void MethodInvokerTypedStaticFourArgsSupportsCapabilities(CapabilityMode mode)
2258
+ {
2259
+ TestMethodClass.ResetStatic();
2260
+ RunInCapabilityMode(
2261
+ mode,
2262
+ () =>
2263
+ {
2264
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2265
+ nameof(TestMethodClass.StaticMethodFourParams)
2266
+ );
2267
+ Func<int, int, int, int, int> invoker =
2268
+ ReflectionHelpers.GetStaticMethodInvoker<int, int, int, int, int>(method);
2269
+ Assert.AreEqual(22, invoker(4, 5, 6, 7));
2270
+ }
2271
+ );
2272
+ }
2273
+
2274
+ [TestCaseSource(nameof(CapabilityModes))]
2275
+ public void ActionInvokerStaticNoArgsSupportsCapabilities(CapabilityMode mode)
2276
+ {
2277
+ TestMethodClass.ResetStatic();
2278
+ RunInCapabilityMode(
2279
+ mode,
2280
+ () =>
2281
+ {
2282
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2283
+ nameof(TestMethodClass.StaticVoidMethod)
2284
+ );
2285
+ Action action = ReflectionHelpers.GetStaticActionInvoker(method);
2286
+ action();
2287
+ Assert.AreEqual(1, TestMethodClass.StaticMethodCallCount);
2288
+ }
2289
+ );
2290
+ }
2291
+
2292
+ [TestCaseSource(nameof(CapabilityModes))]
2293
+ public void ActionInvokerStaticOneArgSupportsCapabilities(CapabilityMode mode)
2294
+ {
2295
+ TestMethodClass.ResetStatic();
2296
+ RunInCapabilityMode(
2297
+ mode,
2298
+ () =>
2299
+ {
2300
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2301
+ nameof(TestMethodClass.StaticVoidMethodWithParam)
2302
+ );
2303
+ Action<int> action = ReflectionHelpers.GetStaticActionInvoker<int>(method);
2304
+ action(15);
2305
+ Assert.AreEqual(15, TestMethodClass.StaticMethodCallCount);
2306
+ }
2307
+ );
2308
+ }
2309
+
2310
+ [TestCaseSource(nameof(CapabilityModes))]
2311
+ public void ActionInvokerStaticTwoArgsSupportsCapabilities(CapabilityMode mode)
2312
+ {
2313
+ TestMethodClass.ResetStatic();
2314
+ RunInCapabilityMode(
2315
+ mode,
2316
+ () =>
2317
+ {
2318
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2319
+ nameof(TestMethodClass.StaticActionTwo)
2320
+ );
2321
+ Action<int, int> action = ReflectionHelpers.GetStaticActionInvoker<int, int>(
2322
+ method
2323
+ );
2324
+ action(3, 9);
2325
+ Assert.AreEqual(12, TestMethodClass.StaticMethodCallCount);
2326
+ }
2327
+ );
2328
+ }
2329
+
2330
+ [TestCaseSource(nameof(CapabilityModes))]
2331
+ public void ActionInvokerStaticThreeArgsSupportsCapabilities(CapabilityMode mode)
2332
+ {
2333
+ TestMethodClass.ResetStatic();
2334
+ RunInCapabilityMode(
2335
+ mode,
2336
+ () =>
2337
+ {
2338
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2339
+ nameof(TestMethodClass.StaticActionThree)
2340
+ );
2341
+ Action<int, int, int> action = ReflectionHelpers.GetStaticActionInvoker<
2342
+ int,
2343
+ int,
2344
+ int
2345
+ >(method);
2346
+ action(1, 2, 3);
2347
+ Assert.AreEqual(6, TestMethodClass.StaticMethodCallCount);
2348
+ }
2349
+ );
2350
+ }
2351
+
2352
+ [TestCaseSource(nameof(CapabilityModes))]
2353
+ public void ActionInvokerStaticFourArgsSupportsCapabilities(CapabilityMode mode)
2354
+ {
2355
+ TestMethodClass.ResetStatic();
2356
+ RunInCapabilityMode(
2357
+ mode,
2358
+ () =>
2359
+ {
2360
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2361
+ nameof(TestMethodClass.StaticActionFour)
2362
+ );
2363
+ Action<int, int, int, int> action = ReflectionHelpers.GetStaticActionInvoker<
2364
+ int,
2365
+ int,
2366
+ int,
2367
+ int
2368
+ >(method);
2369
+ action(1, 1, 1, 1);
2370
+ Assert.AreEqual(4, TestMethodClass.StaticMethodCallCount);
2371
+ }
2372
+ );
2373
+ }
2374
+
2375
+ [TestCaseSource(nameof(CapabilityModes))]
2376
+ public void ActionInvokerInstanceOneArgSupportsCapabilities(CapabilityMode mode)
2377
+ {
2378
+ RunInCapabilityMode(
2379
+ mode,
2380
+ () =>
2381
+ {
2382
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2383
+ nameof(TestMethodClass.InstanceSetOne)
2384
+ );
2385
+ Action<TestMethodClass, int> action =
2386
+ ReflectionHelpers.GetInstanceActionInvoker<TestMethodClass, int>(method);
2387
+ TestMethodClass instance = new();
2388
+ action(instance, 21);
2389
+ Assert.AreEqual(21, instance.instanceMethodCallCount);
2390
+ }
2391
+ );
2392
+ }
2393
+
2394
+ [TestCaseSource(nameof(CapabilityModes))]
2395
+ public void ActionInvokerInstanceTwoArgsSupportsCapabilities(CapabilityMode mode)
2396
+ {
2397
+ RunInCapabilityMode(
2398
+ mode,
2399
+ () =>
2400
+ {
2401
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2402
+ nameof(TestMethodClass.InstanceSetTwo)
2403
+ );
2404
+ Action<TestMethodClass, int, int> action =
2405
+ ReflectionHelpers.GetInstanceActionInvoker<TestMethodClass, int, int>(
2406
+ method
2407
+ );
2408
+ TestMethodClass instance = new();
2409
+ action(instance, 4, 5);
2410
+ Assert.AreEqual(9, instance.instanceMethodCallCount);
2411
+ }
2412
+ );
2413
+ }
2414
+
2415
+ [TestCaseSource(nameof(CapabilityModes))]
2416
+ public void ActionInvokerInstanceThreeArgsSupportsCapabilities(CapabilityMode mode)
2417
+ {
2418
+ RunInCapabilityMode(
2419
+ mode,
2420
+ () =>
2421
+ {
2422
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2423
+ nameof(TestMethodClass.InstanceSetThree)
2424
+ );
2425
+ Action<TestMethodClass, int, int, int> action =
2426
+ ReflectionHelpers.GetInstanceActionInvoker<TestMethodClass, int, int, int>(
2427
+ method
2428
+ );
2429
+ TestMethodClass instance = new();
2430
+ action(instance, 1, 2, 3);
2431
+ Assert.AreEqual(6, instance.instanceMethodCallCount);
2432
+ }
2433
+ );
2434
+ }
2435
+
2436
+ [TestCaseSource(nameof(CapabilityModes))]
2437
+ public void ActionInvokerInstanceFourArgsSupportsCapabilities(CapabilityMode mode)
2438
+ {
2439
+ RunInCapabilityMode(
2440
+ mode,
2441
+ () =>
2442
+ {
2443
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2444
+ nameof(TestMethodClass.InstanceSetFour)
2445
+ );
2446
+ Action<TestMethodClass, int, int, int, int> action =
2447
+ ReflectionHelpers.GetInstanceActionInvoker<
2448
+ TestMethodClass,
2449
+ int,
2450
+ int,
2451
+ int,
2452
+ int
2453
+ >(method);
2454
+ TestMethodClass instance = new();
2455
+ action(instance, 2, 3, 4, 5);
2456
+ Assert.AreEqual(14, instance.instanceMethodCallCount);
2457
+ }
2458
+ );
2459
+ }
2460
+
2461
+ [TestCaseSource(nameof(CapabilityModes))]
2462
+ public void ConstructorInvokerBoxedSupportsCapabilities(CapabilityMode mode)
2463
+ {
2464
+ RunInCapabilityMode(
2465
+ mode,
2466
+ () =>
2467
+ {
2468
+ ConstructorInfo ctor = typeof(TestConstructorClass).GetConstructor(
2469
+ new[] { typeof(int), typeof(string), typeof(bool) }
2470
+ );
2471
+ Func<object[], object> invoker = ReflectionHelpers.GetConstructor(ctor);
2472
+ object result = invoker(new object[] { 7, "seven", true });
2473
+ Assert.IsInstanceOf<TestConstructorClass>(result);
2474
+ TestConstructorClass typed = (TestConstructorClass)result;
2475
+ Assert.AreEqual(7, typed.Value1);
2476
+ Assert.AreEqual("seven", typed.Value2);
2477
+ Assert.IsTrue(typed.Value3);
2478
+ }
2479
+ );
2480
+ }
2481
+
2482
+ [TestCaseSource(nameof(CapabilityModes))]
2483
+ public void ParameterlessConstructorObjectSupportsCapabilities(CapabilityMode mode)
2484
+ {
2485
+ RunInCapabilityMode(
2486
+ mode,
2487
+ () =>
2488
+ {
2489
+ Func<object> creator = ReflectionHelpers.GetParameterlessConstructor(
2490
+ typeof(TestConstructorClass)
2491
+ );
2492
+ object instance = creator();
2493
+ Assert.IsInstanceOf<TestConstructorClass>(instance);
2494
+ }
2495
+ );
2496
+ }
2497
+
2498
+ [TestCaseSource(nameof(CapabilityModes))]
2499
+ public void ParameterlessConstructorTypedSupportsCapabilities(CapabilityMode mode)
2500
+ {
2501
+ RunInCapabilityMode(
2502
+ mode,
2503
+ () =>
2504
+ {
2505
+ Func<TestConstructorClass> creator =
2506
+ ReflectionHelpers.GetParameterlessConstructor<TestConstructorClass>();
2507
+ TestConstructorClass instance = creator();
2508
+ Assert.IsNotNull(instance);
2509
+ Assert.AreEqual("default", instance.Value2);
2510
+ }
2511
+ );
2512
+ }
2513
+
2514
+ [TestCaseSource(nameof(CapabilityModes))]
2515
+ public void GenericParameterlessConstructorSupportsCapabilities(CapabilityMode mode)
2516
+ {
2517
+ RunInCapabilityMode(
2518
+ mode,
2519
+ () =>
2520
+ {
2521
+ Func<List<int>> creator = ReflectionHelpers.GetGenericParameterlessConstructor<
2522
+ List<int>
2523
+ >(typeof(List<>), typeof(int));
2524
+ List<int> list = creator();
2525
+ Assert.IsNotNull(list);
2526
+ Assert.AreEqual(0, list.Count);
2527
+ }
2528
+ );
2529
+ }
2530
+
2531
+ [TestCaseSource(nameof(CapabilityModes))]
2532
+ public void ArrayCreatorTypeSupportsCapabilities(CapabilityMode mode)
2533
+ {
2534
+ RunInCapabilityMode(
2535
+ mode,
2536
+ () =>
2537
+ {
2538
+ Func<int, Array> creator = ReflectionHelpers.GetArrayCreator(typeof(int));
2539
+ Array array = creator(3);
2540
+ Assert.AreEqual(typeof(int[]), array.GetType());
2541
+ array.SetValue(5, 1);
2542
+ Assert.AreEqual(5, array.GetValue(1));
2543
+ }
2544
+ );
2545
+ }
2546
+
2547
+ [TestCaseSource(nameof(CapabilityModes))]
2548
+ public void ArrayCreatorGenericSupportsCapabilities(CapabilityMode mode)
2549
+ {
2550
+ RunInCapabilityMode(
2551
+ mode,
2552
+ () =>
2553
+ {
2554
+ Func<int, string[]> creator = ReflectionHelpers.GetArrayCreator<string>();
2555
+ string[] array = creator(2);
2556
+ array[0] = "hi";
2557
+ Assert.AreEqual("hi", array[0]);
2558
+ }
2559
+ );
2560
+ }
2561
+
2562
+ [TestCaseSource(nameof(CapabilityModes))]
2563
+ public void ListCreatorTypeSupportsCapabilities(CapabilityMode mode)
2564
+ {
2565
+ RunInCapabilityMode(
2566
+ mode,
2567
+ () =>
2568
+ {
2569
+ Func<IList> creator = ReflectionHelpers.GetListCreator(typeof(string));
2570
+ IList list = creator();
2571
+ list.Add("hello");
2572
+ Assert.AreEqual("hello", list[0]);
2573
+ }
2574
+ );
2575
+ }
2576
+
2577
+ [TestCaseSource(nameof(CapabilityModes))]
2578
+ public void ListCreatorGenericSupportsCapabilities(CapabilityMode mode)
2579
+ {
2580
+ RunInCapabilityMode(
2581
+ mode,
2582
+ () =>
2583
+ {
2584
+ Func<IList> creator = ReflectionHelpers.GetListCreator<int>();
2585
+ IList list = creator();
2586
+ list.Add(8);
2587
+ Assert.AreEqual(8, list[0]);
2588
+ }
2589
+ );
2590
+ }
2591
+
2592
+ [TestCaseSource(nameof(CapabilityModes))]
2593
+ public void ListWithCapacityCreatorTypeSupportsCapabilities(CapabilityMode mode)
2594
+ {
2595
+ RunInCapabilityMode(
2596
+ mode,
2597
+ () =>
2598
+ {
2599
+ Func<int, IList> creator = ReflectionHelpers.GetListWithCapacityCreator(
2600
+ typeof(int)
2601
+ );
2602
+ IList list = creator(4);
2603
+ Assert.IsInstanceOf<List<int>>(list);
2604
+ Assert.GreaterOrEqual(((List<int>)list).Capacity, 4);
2605
+ }
2606
+ );
2607
+ }
2608
+
2609
+ [TestCaseSource(nameof(CapabilityModes))]
2610
+ public void ListWithCapacityCreatorGenericSupportsCapabilities(CapabilityMode mode)
2611
+ {
2612
+ RunInCapabilityMode(
2613
+ mode,
2614
+ () =>
2615
+ {
2616
+ Func<int, IList> creator =
2617
+ ReflectionHelpers.GetListWithCapacityCreator<string>();
2618
+ IList list = creator(3);
2619
+ Assert.IsInstanceOf<List<string>>(list);
2620
+ }
2621
+ );
2622
+ }
2623
+
2624
+ [TestCaseSource(nameof(CapabilityModes))]
2625
+ public void HashSetWithCapacityCreatorTypeSupportsCapabilities(CapabilityMode mode)
2626
+ {
2627
+ RunInCapabilityMode(
2628
+ mode,
2629
+ () =>
2630
+ {
2631
+ Func<int, object> creator = ReflectionHelpers.GetHashSetWithCapacityCreator(
2632
+ typeof(int)
2633
+ );
2634
+ object setObject = creator(5);
2635
+ Assert.IsInstanceOf<HashSet<int>>(setObject);
2636
+ }
2637
+ );
2638
+ }
2639
+
2640
+ [TestCaseSource(nameof(CapabilityModes))]
2641
+ public void HashSetWithCapacityCreatorGenericSupportsCapabilities(CapabilityMode mode)
2642
+ {
2643
+ RunInCapabilityMode(
2644
+ mode,
2645
+ () =>
2646
+ {
2647
+ Func<int, HashSet<string>> creator =
2648
+ ReflectionHelpers.GetHashSetWithCapacityCreator<string>();
2649
+ HashSet<string> set = creator(6);
2650
+ Assert.IsNotNull(set);
2651
+ }
2652
+ );
2653
+ }
2654
+
2655
+ [TestCaseSource(nameof(CapabilityModes))]
2656
+ public void HashSetAdderTypeSupportsCapabilities(CapabilityMode mode)
2657
+ {
2658
+ RunInCapabilityMode(
2659
+ mode,
2660
+ () =>
2661
+ {
2662
+ Action<object, object> adder = ReflectionHelpers.GetHashSetAdder(typeof(int));
2663
+ object set = new HashSet<int>();
2664
+ adder(set, 42);
2665
+ HashSet<int> typedSet = (HashSet<int>)set;
2666
+ Assert.IsTrue(typedSet.Contains(42));
2667
+ }
2668
+ );
2669
+ }
2670
+
2671
+ [TestCaseSource(nameof(CapabilityModes))]
2672
+ public void HashSetAdderGenericSupportsCapabilities(CapabilityMode mode)
2673
+ {
2674
+ RunInCapabilityMode(
2675
+ mode,
2676
+ () =>
2677
+ {
2678
+ Action<HashSet<string>, string> adder =
2679
+ ReflectionHelpers.GetHashSetAdder<string>();
2680
+ HashSet<string> set = new();
2681
+ adder(set, "data");
2682
+ Assert.IsTrue(set.Contains("data"));
2683
+ }
2684
+ );
2685
+ }
2686
+
2687
+ [TestCaseSource(nameof(CapabilityModes))]
2688
+ public void DictionaryWithCapacityCreatorTypeSupportsCapabilities(CapabilityMode mode)
2689
+ {
2690
+ RunInCapabilityMode(
2691
+ mode,
2692
+ () =>
2693
+ {
2694
+ Func<int, object> creator = ReflectionHelpers.GetDictionaryWithCapacityCreator(
2695
+ typeof(string),
2696
+ typeof(int)
2697
+ );
2698
+ object dictionary = creator(3);
2699
+ Assert.IsInstanceOf<Dictionary<string, int>>(dictionary);
2700
+ }
2701
+ );
2702
+ }
2703
+
2704
+ [TestCaseSource(nameof(CapabilityModes))]
2705
+ public void DictionaryCreatorGenericSupportsCapabilities(CapabilityMode mode)
2706
+ {
2707
+ RunInCapabilityMode(
2708
+ mode,
2709
+ () =>
2710
+ {
2711
+ Func<int, Dictionary<string, int>> creator =
2712
+ ReflectionHelpers.GetDictionaryCreator<string, int>();
2713
+ Dictionary<string, int> dictionary = creator(2);
2714
+ dictionary["one"] = 1;
2715
+ Assert.AreEqual(1, dictionary["one"]);
2716
+ }
2717
+ );
2718
+ }
2719
+
2720
+ [TestCaseSource(nameof(CapabilityModes))]
2721
+ public void CreateArraySupportsCapabilities(CapabilityMode mode)
2722
+ {
2723
+ RunInCapabilityMode(
2724
+ mode,
2725
+ () =>
2726
+ {
2727
+ Array array = ReflectionHelpers.CreateArray(typeof(int), 2);
2728
+ Assert.AreEqual(typeof(int[]), array.GetType());
2729
+ }
2730
+ );
2731
+ }
2732
+
2733
+ [TestCaseSource(nameof(CapabilityModes))]
2734
+ public void CreateListWithLengthSupportsCapabilities(CapabilityMode mode)
2735
+ {
2736
+ RunInCapabilityMode(
2737
+ mode,
2738
+ () =>
2739
+ {
2740
+ IList list = ReflectionHelpers.CreateList(typeof(int), 3);
2741
+ Assert.That(list, Is.InstanceOf<List<int>>());
2742
+ Assert.That(((List<int>)list).Capacity, Is.EqualTo(3));
2743
+ Assert.That(list.Count, Is.EqualTo(0));
2744
+ }
2745
+ );
2746
+ }
2747
+
2748
+ [TestCaseSource(nameof(CapabilityModes))]
2749
+ public void CreateListSupportsCapabilities(CapabilityMode mode)
2750
+ {
2751
+ RunInCapabilityMode(
2752
+ mode,
2753
+ () =>
2754
+ {
2755
+ IList list = ReflectionHelpers.CreateList(typeof(string));
2756
+ Assert.IsInstanceOf<List<string>>(list);
2757
+ }
2758
+ );
2759
+ }
2760
+
2761
+ [TestCaseSource(nameof(CapabilityModes))]
2762
+ public void CreateHashSetSupportsCapabilities(CapabilityMode mode)
2763
+ {
2764
+ RunInCapabilityMode(
2765
+ mode,
2766
+ () =>
2767
+ {
2768
+ object set = ReflectionHelpers.CreateHashSet(typeof(int), 10);
2769
+ Assert.IsInstanceOf<HashSet<int>>(set);
2770
+ }
2771
+ );
2772
+ }
2773
+
2774
+ [TestCaseSource(nameof(CapabilityModes))]
2775
+ public void CreateDictionarySupportsCapabilities(CapabilityMode mode)
2776
+ {
2777
+ RunInCapabilityMode(
2778
+ mode,
2779
+ () =>
2780
+ {
2781
+ object dictionary = ReflectionHelpers.CreateDictionary(
2782
+ typeof(string),
2783
+ typeof(int),
2784
+ 5
2785
+ );
2786
+ Assert.IsInstanceOf<Dictionary<string, int>>(dictionary);
2787
+ }
2788
+ );
2789
+ }
2790
+
2791
+ [TestCaseSource(nameof(CapabilityModes))]
2792
+ public void CreateInstanceSupportsCapabilities(CapabilityMode mode)
2793
+ {
2794
+ RunInCapabilityMode(
2795
+ mode,
2796
+ () =>
2797
+ {
2798
+ ConstructorInfo ctor = typeof(TestConstructorClass).GetConstructor(
2799
+ new[] { typeof(int), typeof(string) }
2800
+ );
2801
+ object instance = ReflectionHelpers.CreateInstance(ctor, 3, "three");
2802
+ Assert.IsInstanceOf<TestConstructorClass>(instance);
2803
+ Assert.AreEqual("three", ((TestConstructorClass)instance).Value2);
2804
+ }
2805
+ );
2806
+ }
2807
+
2808
+ [TestCaseSource(nameof(CapabilityModes))]
2809
+ public void CreateInstanceGenericSupportsCapabilities(CapabilityMode mode)
2810
+ {
2811
+ RunInCapabilityMode(
2812
+ mode,
2813
+ () =>
2814
+ {
2815
+ TestConstructorClass instance =
2816
+ ReflectionHelpers.CreateInstance<TestConstructorClass>(5, "five", true);
2817
+ Assert.AreEqual(5, instance.Value1);
2818
+ Assert.IsTrue(instance.Value3);
2819
+ }
2820
+ );
2821
+ }
2822
+
2823
+ [TestCaseSource(nameof(CapabilityModes))]
2824
+ public void CreateGenericInstanceSupportsCapabilities(CapabilityMode mode)
2825
+ {
2826
+ RunInCapabilityMode(
2827
+ mode,
2828
+ () =>
2829
+ {
2830
+ List<string> list = ReflectionHelpers.CreateGenericInstance<List<string>>(
2831
+ typeof(List<>),
2832
+ new[] { typeof(string) }
2833
+ );
2834
+ Assert.IsNotNull(list);
2835
+ }
2836
+ );
2837
+ }
2838
+
2839
+ [TestCaseSource(nameof(CapabilityModes))]
2840
+ public void InvokeMethodSupportsCapabilities(CapabilityMode mode)
2841
+ {
2842
+ RunInCapabilityMode(
2843
+ mode,
2844
+ () =>
2845
+ {
2846
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2847
+ nameof(TestMethodClass.InstanceMethodWithParam)
2848
+ );
2849
+ object result = ReflectionHelpers.InvokeMethod(
2850
+ method,
2851
+ new TestMethodClass(),
2852
+ "abcd"
2853
+ );
2854
+ Assert.AreEqual(4, result);
2855
+ }
2856
+ );
2857
+ }
2858
+
2859
+ [TestCaseSource(nameof(CapabilityModes))]
2860
+ public void InvokeStaticMethodSupportsCapabilities(CapabilityMode mode)
2861
+ {
2862
+ TestMethodClass.ResetStatic();
2863
+ RunInCapabilityMode(
2864
+ mode,
2865
+ () =>
2866
+ {
2867
+ MethodInfo method = typeof(TestMethodClass).GetMethod(
2868
+ nameof(TestMethodClass.StaticMethodWithParam)
2869
+ );
2870
+ object result = ReflectionHelpers.InvokeStaticMethod(method, 11);
2871
+ Assert.AreEqual(22, result);
2872
+ }
2873
+ );
2874
+ }
2875
+
2876
+ private static void RunInCapabilityMode(CapabilityMode mode, Action assertion)
2877
+ {
2878
+ switch (mode)
2879
+ {
2880
+ case CapabilityMode.Expressions:
2881
+ using (
2882
+ ReflectionHelpers.OverrideReflectionCapabilities(
2883
+ expressions: true,
2884
+ dynamicIl: ReflectionHelpers.DynamicIlEnabled
2885
+ )
2886
+ )
2887
+ {
2888
+ assertion();
2889
+ }
2890
+ break;
2891
+ case CapabilityMode.DynamicIl:
2892
+ if (!ReflectionHelpers.DynamicIlEnabled)
2893
+ {
2894
+ Assert.Ignore("Dynamic IL is not available on this platform.");
2895
+ }
2896
+
2897
+ using (
2898
+ ReflectionHelpers.OverrideReflectionCapabilities(
2899
+ expressions: false,
2900
+ dynamicIl: true
2901
+ )
2902
+ )
2903
+ {
2904
+ assertion();
2905
+ }
2906
+ break;
2907
+ case CapabilityMode.Reflection:
2908
+ using (
2909
+ ReflectionHelpers.OverrideReflectionCapabilities(
2910
+ expressions: false,
2911
+ dynamicIl: false
2912
+ )
2913
+ )
2914
+ {
2915
+ assertion();
2916
+ }
2917
+ break;
2918
+ default:
2919
+ throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
2920
+ }
2921
+ }
2922
+ }
2923
+ }