#if NET20 || NET30 || !NET_4_6 // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; using System.Dynamic.Utils; using LinqInternal.Core; namespace System.Linq.Expressions.Reimplement { /// /// Represents an expression that has a constant value. /// [DebuggerTypeProxy(typeof(ConstantExpressionProxy))] public class ConstantExpression : Expression { // Possible optimization: we could have a Constant subclass that // stores the unboxed value. private readonly object _value; internal ConstantExpression(object value) { _value = value; } internal static ConstantExpression Make(object value, Type type) { if ((value == null && type == typeof(object)) || (value != null && value.GetType() == type)) { return new ConstantExpression(value); } else { return new TypedConstantExpression(value, type); } } /// /// Gets the static type of the expression that this represents. /// /// The that represents the static type of the expression. public override Type Type { get { if (_value == null) { return typeof(object); } return _value.GetType(); } } /// /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// /// The of the expression. public sealed override ExpressionType NodeType { get { return ExpressionType.Constant; } } /// /// Gets the value of the constant expression. /// public object Value { get { return _value; } } protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitConstant(this); } } internal class TypedConstantExpression : ConstantExpression { private readonly Type _type; internal TypedConstantExpression(object value, Type type) : base(value) { _type = type; } public sealed override Type Type { get { return _type; } } } public partial class Expression { /// /// Creates a that has the property set to the specified value. . /// /// An to set the property equal to. /// /// A that has the property equal to /// and the property set to the specified value. /// public static ConstantExpression Constant(object value) { return ConstantExpression.Make(value, value == null ? typeof(object) : value.GetType()); } /// /// Creates a that has the /// and properties set to the specified values. . /// /// An to set the property equal to. /// A to set the property equal to. /// /// A that has the property equal to /// and the and /// properties set to the specified values. /// public static ConstantExpression Constant(object value, Type type) { ContractUtils.RequiresNotNull(type, "type"); if (value == null && type.IsValueType && !type.IsNullableType()) { throw Error.ArgumentTypesMustMatch(); } if (value != null && !type.IsAssignableFrom(value.GetType())) { throw Error.ArgumentTypesMustMatch(); } return ConstantExpression.Make(value, type); } } } #endif