@@ -184,9 +184,25 @@ private static ParameterExpression TryToMakeKnownTypeParameter(Type type, string
184184 public static readonly ConstantExpression OneConstant = new IntConstantExpression ( 1 ) ;
185185 public static readonly ConstantExpression MinusOneConstant = new IntConstantExpression ( - 1 ) ;
186186
187- public static ConstantRefExpression < T > ConstantRef < T > ( T value ) => new ConstantRefExpression < T > ( value ) ;
187+ /// <summary>Holds the value that you can change lately</summary>
188+ public sealed class ValueRef < T >
189+ {
190+ /// <summary>Reflection access to the value FieldInfo</summary>
191+ public static readonly FieldInfo ValueField = typeof ( ValueRef < T > ) . GetField ( nameof ( Value ) , BindingFlags . Public | BindingFlags . Instance ) ;
192+ /// <summary>The adjustable value</summary>
193+ public T Value ;
194+ /// <summary>Construct with the initial value</summary>
195+ public ValueRef ( T value ) => Value = value ;
196+ }
188197
189- public static ConstantRefExpression ConstantRef ( object value , Type type ) => new ConstantRefExpression ( value , type ) ;
198+ /// <summary>Simplifies the constant which is always hold in Closure and which Value can be modified after the compilation</summary>
199+ public static Expression ConstantRef < T > ( T value , out ValueRef < T > valueRef )
200+ {
201+ valueRef = new ValueRef < T > ( value ) ;
202+
203+ // todo: @perf try the intrinsic?
204+ return new InstanceFieldExpression ( new ValueConstantExpression < ValueRef < T > > ( valueRef ) , ValueRef < T > . ValueField ) ;
205+ }
190206
191207 /// <summary>Avoids the boxing for all (two) bool values</summary>
192208 public static ConstantExpression Constant ( bool value ) => value ? TrueConstant : FalseConstant ;
@@ -3827,10 +3843,6 @@ public abstract class ConstantExpression : Expression
38273843 public sealed override ExpressionType NodeType => ExpressionType . Constant ;
38283844 public abstract object Value { get ; }
38293845
3830- ///<summary>Constant with this field defined will be always put in Closure as a Constant instance and not its value,
3831- /// and will always be accessed by its mutable Field directly, without putting its value into the local variable</summary>
3832- public virtual FieldInfo RefField => null ;
3833-
38343846#if SUPPORTS_VISITOR
38353847 [ RequiresUnreferencedCode ( Trimming . Message ) ]
38363848 protected internal override Expression Accept ( ExpressionVisitor visitor ) => visitor . VisitConstant ( this ) ;
@@ -3869,36 +3881,7 @@ public sealed class ValueConstantExpression<T> : ConstantExpression
38693881 // Note: the Value is specifically an object despite possibility of strongly typed T, because this way it will be a single boxing.
38703882 // Otherwise even using the typed `T _value`, it will be boxed multiple times through its `object Value` accessor.
38713883 public override object Value { get ; }
3872- internal ValueConstantExpression ( object value ) => Value = value ;
3873- }
3874-
3875- /// <summary>A special case of Constant entirely stored in Closure,
3876- /// so that its ValueRef can be updated and the all its Value usage sites will be updated as well, #466.</summary>
3877- public sealed class ConstantRefExpression < T > : ConstantExpression
3878- {
3879- public override Type Type => typeof ( T ) ;
3880- public override object Value => ValueRef ;
3881- private static readonly FieldInfo ValueRefField = typeof ( ConstantRefExpression < T > ) . GetField ( nameof ( ValueRef ) ) ;
3882- public override FieldInfo RefField => ValueRefField ;
3883- public T ValueRef ;
3884- internal ConstantRefExpression ( T value ) => ValueRef = value ;
3885- }
3886-
3887- /// <summary>
3888- /// Note: There is no RefConstantExpression which relies on `Value.GetType()`, because the Value may change (by design), so the Type, which may produce unexpected results.
3889- /// </summary>
3890- public sealed class ConstantRefExpression : ConstantExpression
3891- {
3892- public override Type Type { get ; }
3893- public override object Value => ValueRef ;
3894- public object ValueRef ;
3895- private static readonly FieldInfo ValueRefField = typeof ( ConstantRefExpression ) . GetField ( nameof ( ValueRef ) ) ;
3896- public override FieldInfo RefField => ValueRefField ;
3897- internal ConstantRefExpression ( object value , Type type )
3898- {
3899- Type = type ?? typeof ( object ) ; // The type always should be set
3900- ValueRef = value ;
3901- }
3884+ internal ValueConstantExpression ( T value ) => Value = value ;
39023885}
39033886
39043887public sealed class TypedValueConstantExpression : ConstantExpression
0 commit comments