1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Apache License, Version 2.0, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Apache License, Version 2.0.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System.Diagnostics;
18 using System.Dynamic.Utils;
25 namespace Microsoft.Scripting.Ast {
27 namespace System.Linq.Expressions {
31 /// Represents an expression that has a constant value.
33 [DebuggerTypeProxy(typeof(Expression.ConstantExpressionProxy))]
34 public class ConstantExpression : Expression {
35 // Possible optimization: we could have a Constant<T> subclass that
36 // stores the unboxed value.
37 private readonly object _value;
39 internal ConstantExpression(object value) {
43 internal static ConstantExpression Make(object value, Type type) {
44 if ((value == null && type == typeof(object)) || (value != null && value.GetType() == type)) {
45 return new ConstantExpression(value);
47 return new TypedConstantExpression(value, type);
52 /// Gets the static type of the expression that this <see cref="Expression" /> represents.
54 /// <returns>The <see cref="Type"/> that represents the static type of the expression.</returns>
55 public override Type Type {
58 return typeof(object);
60 return _value.GetType();
65 /// Returns the node type of this Expression. Extension nodes should return
66 /// ExpressionType.Extension when overriding this method.
68 /// <returns>The <see cref="ExpressionType"/> of the expression.</returns>
69 public sealed override ExpressionType NodeType {
70 get { return ExpressionType.Constant; }
73 /// Gets the value of the constant expression.
76 get { return _value; }
80 /// Dispatches to the specific visit method for this node type.
82 protected internal override Expression Accept(ExpressionVisitor visitor) {
83 return visitor.VisitConstant(this);
87 internal class TypedConstantExpression : ConstantExpression {
88 private readonly Type _type;
90 internal TypedConstantExpression(object value, Type type)
95 public sealed override Type Type {
100 public partial class Expression {
102 /// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/> property set to the specified value. .
104 /// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
106 /// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to
107 /// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:Expression.Value"/> property set to the specified value.
109 public static ConstantExpression Constant(object value) {
110 return ConstantExpression.Make(value, value == null ? typeof(object) : value.GetType());
115 /// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/>
116 /// and <see cref="P:ConstantExpression.Type"/> properties set to the specified values. .
118 /// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
119 /// <param name="type">A <see cref="System.Type"/> to set the <see cref="P:Expression.Type"/> property equal to.</param>
121 /// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to
122 /// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:ConstantExpression.Value"/> and
123 /// <see cref="P:Expression.Type"/> properties set to the specified values.
125 public static ConstantExpression Constant(object value, Type type) {
126 ContractUtils.RequiresNotNull(type, "type");
127 if (value == null && type.IsValueType && !TypeUtils.IsNullableType(type)) {
128 throw Error.ArgumentTypesMustMatch();
130 if (value != null && !type.IsAssignableFrom(value.GetType())) {
131 throw Error.ArgumentTypesMustMatch();
133 return ConstantExpression.Make(value, type);