#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