diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index cd67e553..3c14bb2d 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -145,8 +145,8 @@
-
-
-
+
+
+
diff --git a/src/ReactiveUI.Binding.Shared/Expression/ExpressionRewriter.cs b/src/ReactiveUI.Binding.Shared/Expression/ExpressionRewriter.cs
index beaa7bb7..aa480239 100644
--- a/src/ReactiveUI.Binding.Shared/Expression/ExpressionRewriter.cs
+++ b/src/ReactiveUI.Binding.Shared/Expression/ExpressionRewriter.cs
@@ -31,6 +31,8 @@ namespace ReactiveUI.Binding.Expressions;
/// - is stripped.
///
///
+[RequiresUnreferencedCode(
+ "Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
internal sealed class ExpressionRewriter : ExpressionVisitor
{
///
@@ -141,8 +143,6 @@ internal Expression[] VisitArgumentList(ReadOnlyCollection arguments
}
///
- [RequiresUnreferencedCode(
- "Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.Right is not ConstantExpression)
@@ -159,8 +159,6 @@ protected override Expression VisitBinary(BinaryExpression node)
}
///
- [RequiresUnreferencedCode(
- "Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitUnary(UnaryExpression node)
{
// Visit() only routes Convert and ArrayLength here, so no fallthrough is needed.
@@ -178,8 +176,6 @@ protected override Expression VisitUnary(UnaryExpression node)
}
///
- [RequiresUnreferencedCode(
- "Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (!node.Method.IsSpecialName || !AllConstant(node.Arguments))
diff --git a/src/ReactiveUI.Binding.Shared/Expression/Reflection.cs b/src/ReactiveUI.Binding.Shared/Expression/Reflection.cs
index c4a1c2a0..94e4c82b 100644
--- a/src/ReactiveUI.Binding.Shared/Expression/Reflection.cs
+++ b/src/ReactiveUI.Binding.Shared/Expression/Reflection.cs
@@ -15,17 +15,24 @@ namespace ReactiveUI.Binding.Expressions;
/// Helper class for handling reflection and expression-tree related operations.
public static class Reflection
{
- /// Singleton instance of the used for rewriting expression trees.
+ /// Reported when an expression yields no chain to walk.
private const string EmptyExpressionChainMessage = "Expression chain must contain at least one element.";
/// The shared rewriter instance used to simplify expressions before inspection.
- private static readonly ExpressionRewriter ExpressionRewriterInstance = new();
+ ///
+ /// Built on first use rather than in a static initializer. The rewriter reads runtime types by
+ /// reflection and says so, and a static constructor has nowhere to carry that annotation.
+ ///
+ private static ExpressionRewriter? _expressionRewriter;
/// Uses the expression re-writer to simplify the expression down to its simplest expression.
/// The expression to rewrite.
/// The rewritten expression.
+ [RequiresUnreferencedCode(
+ "Expression rewriting uses reflection over runtime types which may be removed by trimming.")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Expression Rewrite(Expression? expression) => ExpressionRewriterInstance.Visit(expression);
+ public static Expression Rewrite(Expression? expression) =>
+ (_expressionRewriter ??= new()).Visit(expression);
/// Converts an expression that points to a property chain into a dotted path string.
/// The expression to generate the property names from.