using System; using System.Reflection; using System.Reflection.Emit; namespace System.Linq.Expressions { /// Represents an expression that has a constant value. // Token: 0x02000017 RID: 23 public sealed class ConstantExpression : Expression { // Token: 0x0600015A RID: 346 RVA: 0x00008C4C File Offset: 0x00006E4C internal ConstantExpression(object value, Type type) : base(ExpressionType.Constant, type) { this.value = value; } /// Gets the value of the constant expression. /// An equal to the value of the represented expression. // Token: 0x1700001A RID: 26 // (get) Token: 0x0600015B RID: 347 RVA: 0x00008C60 File Offset: 0x00006E60 public object Value { get { return this.value; } } // Token: 0x0600015C RID: 348 RVA: 0x00008C68 File Offset: 0x00006E68 internal override void Emit(EmitContext ec) { if (base.Type.IsNullable()) { this.EmitNullableConstant(ec, base.Type, this.value); return; } this.EmitConstant(ec, base.Type, this.value); } // Token: 0x0600015D RID: 349 RVA: 0x00008CAC File Offset: 0x00006EAC private void EmitNullableConstant(EmitContext ec, Type type, object value) { if (value == null) { ILGenerator ig = ec.ig; LocalBuilder localBuilder = ig.DeclareLocal(type); ig.Emit(OpCodes.Ldloca, localBuilder); ig.Emit(OpCodes.Initobj, type); ig.Emit(OpCodes.Ldloc, localBuilder); } else { this.EmitConstant(ec, type.GetFirstGenericArgument(), value); ec.EmitNullableNew(type); } } // Token: 0x0600015E RID: 350 RVA: 0x00008D0C File Offset: 0x00006F0C private void EmitConstant(EmitContext ec, Type type, object value) { ILGenerator ig = ec.ig; switch (Type.GetTypeCode(type)) { case TypeCode.Object: this.EmitIfNotNull(ec, delegate(EmitContext c) { c.EmitReadGlobal(value); }); return; case TypeCode.DBNull: ig.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value", BindingFlags.Static | BindingFlags.Public)); return; case TypeCode.Boolean: if ((bool)this.Value) { ig.Emit(OpCodes.Ldc_I4_1); } else { ec.ig.Emit(OpCodes.Ldc_I4_0); } return; case TypeCode.Char: ig.Emit(OpCodes.Ldc_I4, (int)((char)value)); return; case TypeCode.SByte: ig.Emit(OpCodes.Ldc_I4, (int)((sbyte)value)); return; case TypeCode.Byte: ig.Emit(OpCodes.Ldc_I4, (int)((byte)value)); return; case TypeCode.Int16: ig.Emit(OpCodes.Ldc_I4, (int)((short)value)); return; case TypeCode.UInt16: ig.Emit(OpCodes.Ldc_I4, (int)((ushort)value)); return; case TypeCode.Int32: ig.Emit(OpCodes.Ldc_I4, (int)value); return; case TypeCode.UInt32: ig.Emit(OpCodes.Ldc_I4, (int)((uint)this.Value)); return; case TypeCode.Int64: ig.Emit(OpCodes.Ldc_I8, (long)value); return; case TypeCode.UInt64: ig.Emit(OpCodes.Ldc_I8, (long)((ulong)value)); return; case TypeCode.Single: ig.Emit(OpCodes.Ldc_R4, (float)value); return; case TypeCode.Double: ig.Emit(OpCodes.Ldc_R8, (double)value); return; case TypeCode.Decimal: { decimal num = (decimal)value; int[] bits = decimal.GetBits(num); int num2 = (bits[3] >> 16) & 255; Type typeFromHandle = typeof(int); if (num2 == 0 && num <= 2147483647m && num >= -2147483648m) { ig.Emit(OpCodes.Ldc_I4, (int)num); ig.Emit(OpCodes.Newobj, typeof(decimal).GetConstructor(new Type[] { typeFromHandle })); return; } ig.Emit(OpCodes.Ldc_I4, bits[0]); ig.Emit(OpCodes.Ldc_I4, bits[1]); ig.Emit(OpCodes.Ldc_I4, bits[2]); ig.Emit(OpCodes.Ldc_I4, bits[3] >> 31); ig.Emit(OpCodes.Ldc_I4, num2); ig.Emit(OpCodes.Newobj, typeof(decimal).GetConstructor(new Type[] { typeFromHandle, typeFromHandle, typeFromHandle, typeof(bool), typeof(byte) })); return; } case TypeCode.DateTime: { DateTime dateTime = (DateTime)value; LocalBuilder localBuilder = ig.DeclareLocal(typeof(DateTime)); ig.Emit(OpCodes.Ldloca, localBuilder); ig.Emit(OpCodes.Ldc_I8, dateTime.Ticks); ig.Emit(OpCodes.Ldc_I4, (int)dateTime.Kind); ig.Emit(OpCodes.Call, typeof(DateTime).GetConstructor(new Type[] { typeof(long), typeof(DateTimeKind) })); ig.Emit(OpCodes.Ldloc, localBuilder); return; } case TypeCode.String: this.EmitIfNotNull(ec, delegate(EmitContext c) { c.ig.Emit(OpCodes.Ldstr, (string)value); }); return; } throw new NotImplementedException(string.Format("No support for constants of type {0} yet", base.Type)); } // Token: 0x0600015F RID: 351 RVA: 0x000090E8 File Offset: 0x000072E8 private void EmitIfNotNull(EmitContext ec, Action emit) { if (this.value == null) { ec.ig.Emit(OpCodes.Ldnull); return; } emit(ec); } // Token: 0x04000061 RID: 97 private object value; } }