mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
|
|
namespace CliFx.Schema;
|
|
|
|
/// <summary>
|
|
/// Represents a wrapper around a CLR property that provides read and write access to its value.
|
|
/// </summary>
|
|
public class PropertyBinding(
|
|
[DynamicallyAccessedMembers(
|
|
DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicMethods
|
|
)]
|
|
Type type,
|
|
Func<object, object?> getValue,
|
|
Action<object, object?> setValue
|
|
)
|
|
{
|
|
/// <summary>
|
|
/// Underlying CLR type of the property.
|
|
/// </summary>
|
|
[DynamicallyAccessedMembers(
|
|
DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicMethods
|
|
)]
|
|
public Type Type { get; } = type;
|
|
|
|
/// <summary>
|
|
/// Gets the current value of the property on the specified instance.
|
|
/// </summary>
|
|
public object? GetValue(object instance) => getValue(instance);
|
|
|
|
/// <summary>
|
|
/// Sets the current value of the property on the specified instance.
|
|
/// </summary>
|
|
public void SetValue(object instance, object? value) => setValue(instance, value);
|
|
|
|
internal IReadOnlyList<object?>? TryGetValidValues()
|
|
{
|
|
if (Type.IsEnum)
|
|
{
|
|
var values =
|
|
#if NET7_0_OR_GREATER
|
|
Type.GetEnumValuesAsUnderlyingType();
|
|
#else
|
|
// AOT-compatible APIs are not available here, but it's unlikely
|
|
// that someone will be AOT-compiling a net6.0 or older app anyway.
|
|
Type.GetEnumValues();
|
|
#endif
|
|
|
|
return values.Cast<object?>().ToArray();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Generic version of the type is used to simplify initialization from the source-generated code
|
|
// and to enforce static references to all the types used in the binding.
|
|
// The non-generic version is used internally by the framework when operating in a dynamic context.
|
|
/// <inheritdoc cref="PropertyBinding" />
|
|
public class PropertyBinding<
|
|
TObject,
|
|
[DynamicallyAccessedMembers(
|
|
DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicMethods
|
|
)]
|
|
TProperty
|
|
>(Func<TObject, TProperty?> getValue, Action<TObject, TProperty?> setValue)
|
|
: PropertyBinding(
|
|
typeof(TProperty),
|
|
o => getValue((TObject)o),
|
|
(o, v) => setValue((TObject)o, (TProperty?)v)
|
|
);
|