You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
4.9 KiB
137 lines
4.9 KiB
5 years ago
|
#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
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Represents an expression that has a constant value.
|
||
|
/// </summary>
|
||
|
[DebuggerTypeProxy(typeof(ConstantExpressionProxy))]
|
||
|
public class ConstantExpression : Expression
|
||
|
{
|
||
|
// Possible optimization: we could have a Constant<T> 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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the static type of the expression that this <see cref="Expression" /> represents.
|
||
|
/// </summary>
|
||
|
/// <returns>The <see cref="Type"/> that represents the static type of the expression.</returns>
|
||
|
public override Type Type
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (_value == null)
|
||
|
{
|
||
|
return typeof(object);
|
||
|
}
|
||
|
return _value.GetType();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Returns the node type of this Expression. Extension nodes should return
|
||
|
/// ExpressionType.Extension when overriding this method.
|
||
|
/// </summary>
|
||
|
/// <returns>The <see cref="ExpressionType"/> of the expression.</returns>
|
||
|
public sealed override ExpressionType NodeType
|
||
|
{
|
||
|
get { return ExpressionType.Constant; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the value of the constant expression.
|
||
|
/// </summary>
|
||
|
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
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/> property set to the specified value. .
|
||
|
/// </summary>
|
||
|
/// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
|
||
|
/// <returns>
|
||
|
/// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to
|
||
|
/// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:Expression.Value"/> property set to the specified value.
|
||
|
/// </returns>
|
||
|
public static ConstantExpression Constant(object value)
|
||
|
{
|
||
|
return ConstantExpression.Make(value, value == null ? typeof(object) : value.GetType());
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/>
|
||
|
/// and <see cref="P:ConstantExpression.Type"/> properties set to the specified values. .
|
||
|
/// </summary>
|
||
|
/// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
|
||
|
/// <param name="type">A <see cref="System.Type"/> to set the <see cref="P:Expression.Type"/> property equal to.</param>
|
||
|
/// <returns>
|
||
|
/// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to
|
||
|
/// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:ConstantExpression.Value"/> and
|
||
|
/// <see cref="P:Expression.Type"/> properties set to the specified values.
|
||
|
/// </returns>
|
||
|
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
|