.NET Object Inspector
An efficient .NET object inspector/accesor to avoid reflection usage.
PropertyFetcher, FieldFetcher, MethodCaller and DuckTyping for .NET by Expression Trees or Emitting IL at runtime.
netstandard2.0
, netstandard2.1
, netcoreapp2.0
, netcoreapp2.1
, net461
, net462
, net471
, net472
, net48
and net45
.
Dependencies for netstandard2.0 :
System.Reflection.Emit (>= 4.7.0)
System.Reflection.Emit.Lightweight (>= 4.7.0)
Given the following class with private members, the object inspector can help you to Get, Set or Invoke members of the object instance:
namespace OtherAssembly
{
public class SomeClass
{
private string _privateField = " This field it's so private..." ;
private string PrivateProperty { get ; set ; } = " You can't read this" ;
private void PrivateConsoleWrite ( string line ) => Console. WriteLine ( line) ;
}
public static class ObjectFactory
{
public static object New ( ) => new SomeClass( ) ;
}
}
Note You can inspect, public or non public types with public or non public members, also it's compatible with anonymous objects.
As you can see in the following code:
By using a Duck Typing mechanism
Duck Typing can be done by using an Interface, Abstract class or a class with virtual members. The library will create a proxy type inheriting/implementing the base type.
namespace MyAssembly
{
public interface IDuckSomeClass
{
[ Duck( Name= " _privateField" , Kind = DuckKind. Field, Flags = DuckAttribute. AllFlags) ]
string PrivateField { get ; set ; }
[ Duck( Flags = DuckAttribute. AllFlags) ]
string PrivateProperty { get ; set ; }
[ Duck( Flags = DuckAttribute. AllFlags) ]
void PrivateConsoleWrite ( string line ) ;
}
public class Program
{
public static void Main ( )
{
var obj = OtherAssembly. ObjectFactory. New ( ) ;
HandleObject( obj) ;
}
public static void HandleObject ( object obj )
{
// We can treat the object as it were implementing the IDuckSomeClass interface
var duck = obj. DuckAs < IDuckSomeClass > ( ) ;
Console. WriteLine ( duck. PrivateField) ;
Console. WriteLine ( duck. PrivateProperty) ;
Console. WriteLine ( ) ;
duck. PrivateField += " or not!" ;
duck. PrivateProperty += " . I think I can!" ;
Console. WriteLine ( duck. PrivateField) ;
Console. WriteLine ( duck. PrivateProperty) ;
Console. WriteLine ( ) ;
duck. PrivateConsoleWrite ( " Sooo private..." ) ;
}
}
}
By using a DynamicFetcher
namespace MyAssembly
{
public class Program
{
public static void Main ( )
{
var obj = OtherAssembly. ObjectFactory. New ( ) ;
HandleObject( obj) ;
}
private static readonly DynamicFetcher _privateFieldFetcher = new DynamicFetcher( " _privateField" , DuckAttribute. AllFlags) ;
private static readonly DynamicFetcher _privatePropertyFetcher = new DynamicFetcher( " PrivateProperty" , DuckAttribute. AllFlags) ;
private static readonly DynamicFetcher _privateConsoleWriteFetcher = new DynamicFetcher( " PrivateConsoleWrite" , DuckAttribute. AllFlags) ;
public static void HandleObject ( object obj )
{
// We can handle the object using a dynamic fetcher
Console. WriteLine ( ( string ) _privateFieldFetcher. Fetch ( obj) ) ;
Console. WriteLine ( ( string ) _privatePropertyFetcher. Fetch ( obj) ) ;
Console. WriteLine ( ) ;
_privateFieldFetcher. Shove ( obj, " This field it's so private... or not!" ) ;
_privatePropertyFetcher. Shove ( obj, " You can't read this. I think I can!" ) ;
Console. WriteLine ( ( string ) _privateFieldFetcher. Fetch ( obj) ) ;
Console. WriteLine ( ( string ) _privatePropertyFetcher. Fetch ( obj) ) ;
Console. WriteLine ( ) ;
_privateConsoleWriteFetcher. Invoke ( obj, " Sooo private..." ) ;
}
}
}
By using an Object Inspector
namespace MyAssembly
{
public class Program
{
public static void Main ( )
{
var obj = OtherAssembly. ObjectFactory. New ( ) ;
HandleObject( obj) ;
}
public static void HandleObject ( object obj )
{
var inspector = new ObjectInspector( new InspectName( " _privateField" , DuckAttribute. AllFlags) ,
new InspectName( " PrivateProperty" , DuckAttribute. AllFlags) ,
new InspectName( " PrivateConsoleWrite" , DuckAttribute. AllFlags) ) ;
var viewer = inspector. With ( obj) ;
Console. WriteLine ( ( string ) viewer[ " _privateField" ] ) ;
Console. WriteLine ( ( string ) viewer[ " PrivateProperty" ] ) ;
Console. WriteLine ( ) ;
viewer[ " _privateField" ] = " This field it's so private... or not!" ;
viewer[ " PrivateProperty" ] = " You can't read this. I think I can!" ;
Console. WriteLine ( ( string ) viewer[ " _privateField" ] ) ;
Console. WriteLine ( ( string ) viewer[ " PrivateProperty" ] ) ;
Console. WriteLine ( ) ;
viewer. Invoke ( " PrivateConsoleWrite" , " Sooo private..." ) ;
}
}
}
By using an Inspector Tuple
namespace MyAssembly
{
public class Program
{
public static void Main ( )
{
var obj = OtherAssembly. ObjectFactory. New ( ) ;
HandleObject( obj) ;
}
public static void HandleObject ( object obj )
{
var inspTuple = new InspectorTuple < string , string , object > ( new InspectName( " _privateField" , DuckAttribute. AllFlags) ,
new InspectName( " PrivateProperty" , DuckAttribute. AllFlags) ,
new InspectName( " PrivateConsoleWrite" , DuckAttribute. AllFlags) ) ;
inspTuple. SetInstance ( obj) ;
Console. WriteLine ( inspTuple. Item1) ;
Console. WriteLine ( inspTuple. Item2) ;
Console. WriteLine ( ) ;
inspTuple. Item1 = " This field it's so private... or not!" ;
inspTuple. Item2 = " You can't read this. I think I can!" ;
Console. WriteLine ( inspTuple. Item1) ;
Console. WriteLine ( inspTuple. Item2) ;
Console. WriteLine ( ) ;
inspTuple. InvokeItem3 ( " Sooo private..." ) ;
}
}
}
BenchmarkDotNet =v0.12.1, OS =ubuntu 19.10
AMD Ryzen Threadripper 2950X, 1 CPU, 32 logical and 16 physical cores
.NET Core SDK =3.1.101
[Host] : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
Public Property / Getter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0057 ns
0.0032 ns
0.0030 ns
0.0000 ns
0.0088 ns
0.004
0.00
-
-
-
-
DuckTypeInterface
2.1733 ns
0.0088 ns
0.0082 ns
2.1614 ns
2.1859 ns
1.498
0.01
-
-
-
-
DuckTypeAbstract
1.4507 ns
0.0058 ns
0.0055 ns
1.4409 ns
1.4586 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
1.4454 ns
0.0027 ns
0.0026 ns
1.4419 ns
1.4499 ns
0.996
0.00
-
-
-
-
ExpressionTreeFetcher
4.3870 ns
0.0163 ns
0.0136 ns
4.3561 ns
4.4048 ns
3.024
0.01
-
-
-
-
EmitFetcher
4.4331 ns
0.0154 ns
0.0144 ns
4.4125 ns
4.4654 ns
3.056
0.01
-
-
-
-
DelegateFetcher
6.4340 ns
0.0188 ns
0.0176 ns
6.3985 ns
6.4617 ns
4.435
0.02
-
-
-
-
Reflection
107.0668 ns
0.2081 ns
0.1845 ns
106.6127 ns
107.2895 ns
73.802
0.32
-
-
-
-
Public Property / Getter / Value Type
Method
Mean
Error
StdDev
Median
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.000
0.00
-
-
-
-
DuckTypeInterface
1.6644 ns
0.0080 ns
0.0075 ns
1.6657 ns
1.6513 ns
1.6773 ns
1.193
0.01
-
-
-
-
DuckTypeAbstract
1.3947 ns
0.0074 ns
0.0069 ns
1.3967 ns
1.3803 ns
1.4034 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
1.4578 ns
0.0124 ns
0.0116 ns
1.4568 ns
1.4429 ns
1.4750 ns
1.045
0.01
-
-
-
-
ExpressionTreeFetcher
12.2679 ns
0.2723 ns
0.5438 ns
12.5072 ns
10.9949 ns
12.9669 ns
8.489
0.45
0.0014
-
-
24 B
EmitFetcher
12.0793 ns
0.2696 ns
0.2648 ns
12.1251 ns
11.6069 ns
12.6324 ns
8.654
0.21
0.0014
-
-
24 B
DelegateFetcher
15.7135 ns
0.1862 ns
0.1742 ns
15.8033 ns
15.3563 ns
15.8849 ns
11.267
0.16
0.0014
-
-
24 B
Reflection
165.7264 ns
0.7783 ns
0.7280 ns
165.4518 ns
164.8954 ns
167.2588 ns
118.828
0.89
0.0014
-
-
24 B
Public Property / Setter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
1.433 ns
0.0095 ns
0.0079 ns
1.421 ns
1.446 ns
0.60
0.00
-
-
-
-
DuckTypeInterface
2.870 ns
0.0080 ns
0.0071 ns
2.856 ns
2.885 ns
1.21
0.00
-
-
-
-
DuckTypeAbstract
2.371 ns
0.0063 ns
0.0049 ns
2.357 ns
2.377 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.366 ns
0.0081 ns
0.0068 ns
2.349 ns
2.376 ns
1.00
0.00
-
-
-
-
ExpressionTreeFetcher
5.161 ns
0.0469 ns
0.0439 ns
5.074 ns
5.232 ns
2.18
0.01
-
-
-
-
EmitFetcher
5.181 ns
0.0524 ns
0.0490 ns
5.073 ns
5.256 ns
2.18
0.03
-
-
-
-
DelegateFetcher
9.957 ns
0.1754 ns
0.1641 ns
9.701 ns
10.243 ns
4.22
0.07
-
-
-
-
Reflection
215.519 ns
0.7459 ns
0.6977 ns
213.798 ns
216.511 ns
90.86
0.29
0.0038
-
-
64 B
Public Property / Setter / Value Type
Method
Mean
Error
StdDev
Median
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.0000 ns
0.000
0.00
-
-
-
-
DuckTypeInterface
4.0533 ns
0.1463 ns
0.4199 ns
4.1939 ns
2.6805 ns
4.9533 ns
1.095
0.07
-
-
-
-
DuckTypeAbstract
3.8792 ns
0.0550 ns
0.0514 ns
3.9012 ns
3.7611 ns
3.9309 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
3.9063 ns
0.0546 ns
0.0511 ns
3.9051 ns
3.7578 ns
3.9538 ns
1.007
0.01
-
-
-
-
ExpressionTreeFetcher
12.7433 ns
0.2835 ns
0.6572 ns
13.0110 ns
11.1596 ns
13.6258 ns
3.222
0.21
0.0014
-
-
24 B
EmitFetcher
11.2177 ns
0.2420 ns
0.4110 ns
11.2254 ns
10.5157 ns
12.1097 ns
2.898
0.13
0.0014
-
-
24 B
DelegateFetcher
15.0292 ns
0.0974 ns
0.0864 ns
15.0117 ns
14.9219 ns
15.2370 ns
3.877
0.06
0.0014
-
-
24 B
Reflection
226.4618 ns
1.1025 ns
0.9774 ns
226.7582 ns
223.5496 ns
227.3624 ns
58.419
0.91
0.0052
-
-
88 B
Public Field / Getter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0162 ns
0.0024 ns
0.0023 ns
0.0127 ns
0.0196 ns
0.01
0.00
-
-
-
-
DuckTypeInterface
1.6780 ns
0.0035 ns
0.0033 ns
1.6705 ns
1.6825 ns
1.20
0.01
-
-
-
-
DuckTypeAbstract
1.4006 ns
0.0050 ns
0.0046 ns
1.3933 ns
1.4075 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
1.3839 ns
0.0032 ns
0.0025 ns
1.3799 ns
1.3882 ns
0.99
0.00
-
-
-
-
ExpressionTreeFetcher
4.4193 ns
0.0225 ns
0.0211 ns
4.3882 ns
4.4517 ns
3.16
0.02
-
-
-
-
EmitFetcher
4.4563 ns
0.0221 ns
0.0207 ns
4.4206 ns
4.4880 ns
3.18
0.02
-
-
-
-
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
48.7989 ns
0.1460 ns
0.1294 ns
48.6077 ns
49.0602 ns
34.84
0.12
-
-
-
-
Public Field / Getter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0104 ns
0.0051 ns
0.0048 ns
0.0029 ns
0.0198 ns
0.008
0.00
-
-
-
-
DuckTypeInterface
1.6868 ns
0.0067 ns
0.0063 ns
1.6743 ns
1.6995 ns
1.216
0.01
-
-
-
-
DuckTypeAbstract
1.3874 ns
0.0045 ns
0.0042 ns
1.3799 ns
1.3937 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
1.3971 ns
0.0042 ns
0.0038 ns
1.3869 ns
1.4013 ns
1.007
0.00
-
-
-
-
ExpressionTreeFetcher
12.3567 ns
0.2692 ns
0.3773 ns
11.3392 ns
13.0537 ns
8.883
0.33
0.0014
-
-
24 B
EmitFetcher
12.7230 ns
0.2337 ns
0.2186 ns
12.1087 ns
12.9269 ns
9.170
0.15
0.0014
-
-
24 B
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
74.5795 ns
0.6475 ns
0.6057 ns
73.7307 ns
75.4323 ns
53.754
0.41
0.0014
-
-
24 B
Public Field / Setter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
1.195 ns
0.0070 ns
0.0065 ns
1.186 ns
1.205 ns
0.50
0.00
-
-
-
-
DuckTypeInterface
2.638 ns
0.0171 ns
0.0160 ns
2.610 ns
2.662 ns
1.09
0.01
-
-
-
-
DuckTypeAbstract
2.409 ns
0.0069 ns
0.0064 ns
2.392 ns
2.417 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.411 ns
0.0056 ns
0.0053 ns
2.400 ns
2.419 ns
1.00
0.00
-
-
-
-
ExpressionTreeFetcher
4.879 ns
0.0398 ns
0.0372 ns
4.816 ns
4.948 ns
2.03
0.02
-
-
-
-
EmitFetcher
4.798 ns
0.0265 ns
0.0248 ns
4.756 ns
4.840 ns
1.99
0.01
-
-
-
-
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
62.681 ns
0.1221 ns
0.1142 ns
62.487 ns
62.922 ns
26.02
0.08
-
-
-
-
Public Field / Setter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0161 ns
0.0066 ns
0.0058 ns
0.0069 ns
0.0277 ns
0.004
0.00
-
-
-
-
DuckTypeInterface
4.1358 ns
0.1109 ns
0.1442 ns
3.6628 ns
4.2307 ns
1.028
0.04
-
-
-
-
DuckTypeAbstract
3.9717 ns
0.0101 ns
0.0085 ns
3.9483 ns
3.9830 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
3.9130 ns
0.0182 ns
0.0171 ns
3.8800 ns
3.9475 ns
0.985
0.01
-
-
-
-
ExpressionTreeFetcher
10.2799 ns
0.1900 ns
0.1777 ns
10.1394 ns
10.6424 ns
2.590
0.05
0.0014
-
-
24 B
EmitFetcher
10.2794 ns
0.1665 ns
0.1710 ns
10.0566 ns
10.6314 ns
2.586
0.05
0.0014
-
-
24 B
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
78.7027 ns
0.2133 ns
0.1891 ns
78.3381 ns
78.9225 ns
19.823
0.06
0.0014
-
-
24 B
Method
Mean
Error
StdDev
Median
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
0.0042 ns
0.0042 ns
0.0039 ns
0.0028 ns
0.0000 ns
0.0118 ns
0.002
0.00
-
-
-
-
DuckTypeInterface
2.4260 ns
0.0095 ns
0.0089 ns
2.4228 ns
2.4145 ns
2.4431 ns
1.415
0.01
-
-
-
-
DuckTypeAbstract
1.7151 ns
0.0077 ns
0.0072 ns
1.7147 ns
1.7045 ns
1.7298 ns
1.000
0.00
-
-
-
-
DuckTypeVirtual
1.7322 ns
0.0082 ns
0.0077 ns
1.7330 ns
1.7175 ns
1.7472 ns
1.010
0.01
-
-
-
-
ExpressionTreeFetcher
48.6474 ns
0.6056 ns
0.5665 ns
48.8195 ns
46.8674 ns
49.2839 ns
28.364
0.35
0.0067
-
-
112 B
EmitFetcher
48.7790 ns
0.1421 ns
0.1186 ns
48.7748 ns
48.5905 ns
49.0109 ns
28.432
0.14
0.0067
-
-
112 B
DelegateFetcher
NA
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
351.2802 ns
0.9316 ns
0.8258 ns
351.4524 ns
349.1993 ns
352.0959 ns
204.823
0.96
0.0091
-
-
152 B
Private Property / Getter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
2.671 ns
0.0046 ns
0.0043 ns
2.666 ns
2.681 ns
1.11
0.00
-
-
-
-
DuckTypeAbstract
2.408 ns
0.0077 ns
0.0072 ns
2.398 ns
2.422 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.154 ns
0.0070 ns
0.0065 ns
2.145 ns
2.166 ns
0.89
0.00
-
-
-
-
ExpressionTreeFetcher
4.444 ns
0.0162 ns
0.0144 ns
4.421 ns
4.469 ns
1.85
0.01
-
-
-
-
EmitFetcher
4.427 ns
0.0241 ns
0.0225 ns
4.398 ns
4.470 ns
1.84
0.01
-
-
-
-
DelegateFetcher
6.422 ns
0.0151 ns
0.0134 ns
6.402 ns
6.439 ns
2.67
0.01
-
-
-
-
Reflection
106.718 ns
0.2564 ns
0.2273 ns
106.414 ns
107.070 ns
44.31
0.16
-
-
-
-
Private Property / Getter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
2.881 ns
0.0089 ns
0.0083 ns
2.863 ns
2.891 ns
1.19
0.01
-
-
-
-
DuckTypeAbstract
2.413 ns
0.0105 ns
0.0099 ns
2.388 ns
2.426 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.415 ns
0.0088 ns
0.0074 ns
2.397 ns
2.426 ns
1.00
0.01
-
-
-
-
ExpressionTreeFetcher
12.329 ns
0.2724 ns
0.2548 ns
11.700 ns
12.732 ns
5.11
0.12
0.0014
-
-
24 B
EmitFetcher
12.127 ns
0.2682 ns
0.4482 ns
10.431 ns
12.552 ns
4.99
0.19
0.0014
-
-
24 B
DelegateFetcher
14.618 ns
0.2838 ns
0.2655 ns
14.230 ns
14.984 ns
6.06
0.10
0.0014
-
-
24 B
Reflection
170.210 ns
1.0057 ns
0.9407 ns
168.702 ns
171.906 ns
70.55
0.55
0.0014
-
-
24 B
Private Property / Setter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
3.967 ns
0.0965 ns
0.0903 ns
3.764 ns
4.097 ns
1.09
0.02
-
-
-
-
DuckTypeAbstract
3.639 ns
0.0086 ns
0.0076 ns
3.626 ns
3.652 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
3.647 ns
0.0076 ns
0.0071 ns
3.638 ns
3.657 ns
1.00
0.00
-
-
-
-
ExpressionTreeFetcher
4.728 ns
0.1222 ns
0.1143 ns
4.503 ns
4.838 ns
1.30
0.03
-
-
-
-
EmitFetcher
4.765 ns
0.1213 ns
0.1075 ns
4.393 ns
4.803 ns
1.31
0.03
-
-
-
-
DelegateFetcher
10.804 ns
0.2419 ns
0.2971 ns
9.875 ns
11.082 ns
2.97
0.09
-
-
-
-
Reflection
190.189 ns
1.3800 ns
1.2908 ns
188.956 ns
193.633 ns
52.23
0.36
0.0038
-
-
64 B
Private Property / Setter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
3.686 ns
0.0158 ns
0.0148 ns
3.660 ns
3.708 ns
1.02
0.01
-
-
-
-
DuckTypeAbstract
3.612 ns
0.0239 ns
0.0224 ns
3.589 ns
3.652 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
3.628 ns
0.0100 ns
0.0078 ns
3.614 ns
3.639 ns
1.00
0.01
-
-
-
-
ExpressionTreeFetcher
11.522 ns
0.3087 ns
0.9103 ns
10.283 ns
13.249 ns
3.02
0.20
0.0014
-
-
24 B
EmitFetcher
10.236 ns
0.2166 ns
0.4015 ns
9.821 ns
11.229 ns
2.89
0.10
0.0014
-
-
24 B
DelegateFetcher
14.316 ns
0.1558 ns
0.1457 ns
13.995 ns
14.607 ns
3.96
0.05
0.0014
-
-
24 B
Reflection
207.938 ns
1.0840 ns
1.0139 ns
206.318 ns
210.046 ns
57.57
0.50
0.0052
-
-
88 B
Private Field / Getter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
3.147 ns
0.0216 ns
0.0191 ns
3.125 ns
3.180 ns
1.30
0.01
-
-
-
-
DuckTypeAbstract
2.420 ns
0.0050 ns
0.0045 ns
2.408 ns
2.425 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.407 ns
0.0151 ns
0.0126 ns
2.387 ns
2.432 ns
0.99
0.01
-
-
-
-
ExpressionTreeFetcher
4.480 ns
0.0549 ns
0.0487 ns
4.415 ns
4.588 ns
1.85
0.02
-
-
-
-
EmitFetcher
4.401 ns
0.0182 ns
0.0162 ns
4.366 ns
4.428 ns
1.82
0.01
-
-
-
-
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
49.517 ns
0.2291 ns
0.2143 ns
49.099 ns
49.789 ns
20.48
0.09
-
-
-
-
Private Field / Getter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
2.847 ns
0.0154 ns
0.0137 ns
2.814 ns
2.864 ns
1.20
0.01
-
-
-
-
DuckTypeAbstract
2.381 ns
0.0164 ns
0.0137 ns
2.358 ns
2.402 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
2.396 ns
0.0074 ns
0.0069 ns
2.382 ns
2.408 ns
1.01
0.01
-
-
-
-
ExpressionTreeFetcher
11.441 ns
0.2568 ns
0.6584 ns
10.388 ns
13.203 ns
4.99
0.27
0.0014
-
-
24 B
EmitFetcher
12.052 ns
0.2697 ns
0.4652 ns
10.618 ns
12.944 ns
5.12
0.26
0.0014
-
-
24 B
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
81.354 ns
0.9989 ns
0.8855 ns
79.770 ns
82.538 ns
34.14
0.50
0.0014
-
-
24 B
Private Field / Setter / Object Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
3.605 ns
0.0140 ns
0.0117 ns
3.578 ns
3.619 ns
0.99
0.00
-
-
-
-
DuckTypeAbstract
3.649 ns
0.0149 ns
0.0140 ns
3.625 ns
3.675 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
3.656 ns
0.0169 ns
0.0158 ns
3.629 ns
3.676 ns
1.00
0.00
-
-
-
-
ExpressionTreeFetcher
4.772 ns
0.0397 ns
0.0371 ns
4.715 ns
4.816 ns
1.31
0.01
-
-
-
-
EmitFetcher
4.822 ns
0.0209 ns
0.0174 ns
4.784 ns
4.858 ns
1.32
0.01
-
-
-
-
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
61.724 ns
0.2886 ns
0.2559 ns
61.262 ns
62.284 ns
16.91
0.10
-
-
-
-
Private Field / Setter / Value Type
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
3.701 ns
0.0248 ns
0.0207 ns
3.673 ns
3.729 ns
1.02
0.01
-
-
-
-
DuckTypeAbstract
3.633 ns
0.0218 ns
0.0182 ns
3.605 ns
3.663 ns
1.00
0.00
-
-
-
-
DuckTypeVirtual
3.635 ns
0.0262 ns
0.0232 ns
3.587 ns
3.666 ns
1.00
0.01
-
-
-
-
ExpressionTreeFetcher
10.347 ns
0.1572 ns
0.1393 ns
10.118 ns
10.510 ns
2.85
0.04
0.0014
-
-
24 B
EmitFetcher
10.958 ns
0.2460 ns
0.5188 ns
10.207 ns
12.344 ns
3.00
0.15
0.0014
-
-
24 B
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
72.224 ns
0.4226 ns
0.3953 ns
71.470 ns
72.778 ns
19.87
0.19
0.0014
-
-
24 B
Method
Mean
Error
StdDev
Min
Max
Ratio
RatioSD
Gen 0
Gen 1
Gen 2
Allocated
Direct
NA
NA
NA
NA
NA
?
?
-
-
-
-
DuckTypeInterface
59.46 ns
0.536 ns
0.476 ns
58.59 ns
60.31 ns
1.03
0.01
0.0067
-
-
112 B
DuckTypeAbstract
57.49 ns
0.568 ns
0.531 ns
56.77 ns
58.35 ns
1.00
0.00
0.0067
-
-
112 B
DuckTypeVirtual
56.76 ns
0.176 ns
0.164 ns
56.50 ns
56.99 ns
0.99
0.01
0.0067
-
-
112 B
ExpressionTreeFetcher
48.86 ns
0.301 ns
0.281 ns
48.43 ns
49.32 ns
0.85
0.01
0.0067
-
-
112 B
EmitFetcher
49.22 ns
0.565 ns
0.472 ns
48.42 ns
49.90 ns
0.86
0.01
0.0067
-
-
112 B
DelegateFetcher
NA
NA
NA
NA
NA
?
?
-
-
-
-
Reflection
355.14 ns
2.225 ns
2.082 ns
351.81 ns
358.70 ns
6.18
0.06
0.0091
-
-
152 B
Thanks to @jetbrains for helping on this development with the licenses for Rider, dotTrace and dotMemory