Note
public sealed class FieldAccessor : MemberAccessor
Public NotInheritable Class FieldAccessor
Inherits MemberAccessor
public ref class FieldAccessor sealed : public MemberAccessor
[<SealedAttribute>]
type FieldAccessor =
class
inherit MemberAccessor
end
You can obtain a FieldAccessor instance by the static GetAccessor method.
The non-generic Get and Set methods can be used to get and set the field in general cases.
If you know the field type at compile time, then you can use the generic GetStaticValue/SetStaticValue methods for static fields. If you know also the instance type, then the GetInstanceValue/SetInstanceValue methods can be used to access instance fields with better performance.
The first call of these methods are slower because the delegates are generated on the first access, but further calls are much faster.
The already obtained accessors are cached so subsequent GetAccessor calls return the already created accessors unless they were dropped out from the cache, which can store about 8000 elements.
using System;
using System.Reflection;
using System.Runtime.Versioning;
using KGySoft.Diagnostics;
using KGySoft.Reflection;
class Example
{
private class TestClass
{
public int TestField;
}
private static string PlatformName => ((TargetFrameworkAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
typeof(TargetFrameworkAttribute))).FrameworkDisplayName;
static void Main(string[] args)
{
var instance = new TestClass();
FieldInfo field = instance.GetType().GetField(nameof(TestClass.TestField));
FieldAccessor accessor = FieldAccessor.GetAccessor(field);
new PerformanceTest { TestName = $"Set Field - {PlatformName}", Iterations = 1_000_000 }
.AddCase(() => instance.TestField = 1, "Direct set")
.AddCase(() => field.SetValue(instance, 1), "System.Reflection.FieldInfo.SetValue")
.AddCase(() => accessor.Set(instance, 1), "FieldAccessor.Set")
.AddCase(() => accessor.SetInstanceValue(instance, 1), "FieldAccessor.SetInstanceValue<,>")
.DoTest()
.DumpResults(Console.Out);
new PerformanceTest<int> { TestName = $"Get Field - {PlatformName}", Iterations = 1_000_000 }
.AddCase(() => instance.TestField, "Direct get")
.AddCase(() => (int)field.GetValue(instance), "System.Reflection.FieldInfo.GetValue")
.AddCase(() => (int)accessor.Get(instance), "FieldAccessor.Get")
.AddCase(() => accessor.GetInstanceValue<TestClass, int>(instance), "FieldAccessor.GetInstanceValue<,>")
.DoTest()
.DumpResults(Console.Out);
}
}
// This code example produces a similar output to these ones:
// ==[Set Field - .NET 8.0 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 4
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct set: average time: 2.83 ms
// 2. FieldAccessor.SetInstanceValue<,>: average time: 4.53 ms (+1.71 ms / 160.31%)
// 3. FieldAccessor.Set: average time: 10.84 ms (+8.01 ms / 383.41%)
// 4. System.Reflection.FieldInfo.SetValue: average time: 52.15 ms (+49.33 ms / 1,844.55%)
//
// ==[Get Field - .NET 8.0 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 4
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct get: average time: 2.83 ms
// 2. FieldAccessor.GetInstanceValue<,>: average time: 3.75 ms (+0.92 ms / 132.42%)
// 3. FieldAccessor.Get: average time: 10.18 ms (+7.35 ms / 359.81%)
// 4. System.Reflection.FieldInfo.GetValue: average time: 54.13 ms (+51.30 ms / 1,913.66%)
// ==[Set Field - .NET Framework 4.8 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 4
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct set: average time: 3.11 ms
// 2. FieldAccessor.SetInstanceValue<,>: average time: 11.45 ms (+8.34 ms / 367.99%)
// 3. FieldAccessor.Set: average time: 13.65 ms (+10.54 ms / 438.45%)
// 4. System.Reflection.FieldInfo.SetValue: average time: 99.95 ms (+96.84 ms / 3,211.03%)
//
// ==[Get Field - .NET Framework 4.8 Results]================================================
// Iterations: 1,000,000
// Warming up: Yes
// Test cases: 4
// Calling GC.Collect: Yes
// Forced CPU Affinity: No
// Cases are sorted by time (quickest first)
// --------------------------------------------------
// 1. Direct get: average time: 2.15 ms
// 2. FieldAccessor.GetInstanceValue<,>: average time: 10.24 ms (+8.09 ms / 476.41%)
// 3. FieldAccessor.Get: average time: 10.56 ms (+8.41 ms / 491.29%)
// 4. System.Reflection.FieldInfo.GetValue: average time: 75.45 ms (+73.30 ms / 3,509.27%)
IsConstant | Gets whether the field is a constant. Constant fields cannot be set. |
IsReadOnly | Gets whether the field is read-only. |
MemberInfo |
Gets the reflection member info of the accessed member.
(Inherited from MemberAccessor) |
Equals |
Determines whether the specified Object is equal to the current MemberAccessor.
(Inherited from MemberAccessor) |
Get | Gets the value of the field. For static fields the instance parameter is omitted (can be ). |
GetAccessor | Gets a FieldAccessor for the specified field. |
GetHashCode |
Gets a hash code for the current MemberAccessor instance.
(Inherited from MemberAccessor) |
GetInstanceValueTInstance, TField(TInstance) | Gets the strongly typed value of an instance field in a reference type. If the type of the field or the declaring instance is not known at compile time the non-generic Get method can be used. |
GetInstanceValueTInstance, TField(TInstance) | Gets the strongly typed value of an instance field in a value type. If the type of the field or the declaring instance is not known at compile time the non-generic Get method can be used. |
GetStaticValueTField | Gets the strongly typed value of a static field. If the type of the field is not known at compile time the non-generic Get method can be used. |
Set | Sets the field. For static fields the instance parameter is omitted (can be ). |
SetInstanceValueTInstance, TField(TInstance, TField) | Sets the strongly typed value of an instance field in a value type. If the type of the field or the declaring instance is not known at compile time the non-generic Set method can be used. |
SetInstanceValueTInstance, TField(TInstance, TField) | Sets the strongly typed value of an instance field in a reference type. If the type of the field or the declaring instance is not known at compile time the non-generic Set method can be used. |
SetStaticValueTField | Sets the strongly typed value of a static field. If the type of the field is not known at compile time the non-generic Set method can be used. |
ToString |
Returns a String that represents the current MemberAccessor.
(Inherited from MemberAccessor) |
Convert |
Converts an Object specified in the obj parameter to the desired targetType.
See the Examples section of the generic ConvertTTarget(Object, CultureInfo) overload for an example. (Defined by ObjectExtensions) |
ConvertTTarget |
Converts an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions) |
In |
Gets whether item is among the elements of set.
See the Examples section of the generic InT(T, T) overload for an example. (Defined by ObjectExtensions) |
TryConvert |
Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvert |
Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvertTTarget |
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvertTTarget |
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |