Browse Source

Add TObject overload for GetPrivateField

pull/333/head
Ionite 12 months ago
parent
commit
38b570e998
No known key found for this signature in database
  1. 42
      StabilityMatrix.Core/Extensions/ObjectExtensions.cs
  2. 1
      StabilityMatrix.Core/StabilityMatrix.Core.csproj

42
StabilityMatrix.Core/Extensions/ObjectExtensions.cs

@ -1,8 +1,10 @@
using System.Reflection;
using JetBrains.Annotations;
using RockLib.Reflection.Optimized;
namespace StabilityMatrix.Core.Extensions;
[PublicAPI]
public static class ObjectExtensions
{
/// <summary>
@ -24,6 +26,10 @@ public static class ObjectExtensions
/// <summary>
/// Get the value of a named private field from an object
/// </summary>
/// <remarks>
/// The field must be defined by the runtime type of <see cref="obj"/> or its first base type.
/// For higher inheritance levels, use <see cref="GetPrivateField{TObject,T}"/> to specify the exact defining type.
/// </remarks>
public static T? GetPrivateField<T>(this object obj, string fieldName)
{
// Check cache
@ -55,6 +61,42 @@ public static class ObjectExtensions
return (T?)fieldGetter(obj);
}
/// <summary>
/// Get the value of a named private field from an object
/// </summary>
/// <typeparam name="TObject">Type of the object that defines the field, must be a base class of <see cref="obj"/></typeparam>
/// <typeparam name="T">Type of the field</typeparam>
public static T? GetPrivateField<TObject, T>(this TObject obj, string fieldName)
where TObject : class
{
// Check cache
var fieldGetterCache = FieldGetterTypeCache.GetOrAdd(typeof(TObject));
if (!fieldGetterCache.TryGetValue(fieldName, out var fieldGetter))
{
// Get the field
var field = typeof(TObject).GetField(
fieldName,
BindingFlags.Instance | BindingFlags.NonPublic
);
if (field is null)
{
throw new ArgumentException(
$"Field {typeof(TObject).Name}.{fieldName} not found on type {obj.GetType().Name}"
);
}
// Create a getter for the field
fieldGetter = field.CreateGetter();
// Add to cache
fieldGetterCache.Add(fieldName, fieldGetter);
}
return (T?)fieldGetter(obj);
}
/// <summary>
/// Set the value of a named private field on an object
/// </summary>

1
StabilityMatrix.Core/StabilityMatrix.Core.csproj

@ -25,6 +25,7 @@
<PackageReference Include="DeviceId.Windows" Version="6.5.0" />
<PackageReference Include="DeviceId.Windows.Wmi" Version="6.5.1" />
<PackageReference Include="DynamicData" Version="8.1.1" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="LiteDB" Version="5.0.17" />
<PackageReference Include="LiteDB.Async" Version="0.1.7" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" />

Loading…
Cancel
Save