ConstVal
struct ConstVal
using System;
using System.Globalization;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
internal readonly struct ConstVal
{
private static readonly object s_false = false;
private static readonly object s_true = true;
private static readonly object s_zeroInt32 = 0;
public object ObjectVal { get; }
public bool BooleanVal => SpecialUnbox<bool>(ObjectVal);
public sbyte SByteVal => SpecialUnbox<sbyte>(ObjectVal);
public byte ByteVal => SpecialUnbox<byte>(ObjectVal);
public short Int16Val => SpecialUnbox<short>(ObjectVal);
public ushort UInt16Val => SpecialUnbox<ushort>(ObjectVal);
public int Int32Val => SpecialUnbox<int>(ObjectVal);
public uint UInt32Val => SpecialUnbox<uint>(ObjectVal);
public long Int64Val => SpecialUnbox<long>(ObjectVal);
public ulong UInt64Val => SpecialUnbox<ulong>(ObjectVal);
public float SingleVal => SpecialUnbox<float>(ObjectVal);
public double DoubleVal => SpecialUnbox<double>(ObjectVal);
public decimal DecimalVal => SpecialUnbox<decimal>(ObjectVal);
public char CharVal => SpecialUnbox<char>(ObjectVal);
public string StringVal => SpecialUnbox<string>(ObjectVal);
public bool IsNullRef => ObjectVal == null;
private ConstVal(object value)
{
ObjectVal = value;
}
public bool IsZero(ConstValKind kind)
{
switch (kind) {
case ConstValKind.Decimal:
return DecimalVal == decimal.Zero;
case ConstValKind.String:
return false;
default:
return IsDefault(ObjectVal);
}
}
private static T SpecialUnbox<T>(object o)
{
if (IsDefault(o))
return default(T);
return (T)Convert.ChangeType(o, typeof(T), CultureInfo.InvariantCulture);
}
private static bool IsDefault(object o)
{
if (o != null) {
switch (Type.GetTypeCode(o.GetType())) {
case TypeCode.Boolean:
return false.Equals(o);
case TypeCode.SByte:
return ((sbyte)0).Equals(o);
case TypeCode.Byte:
return ((byte)0).Equals(o);
case TypeCode.Int16:
return ((short)0).Equals(o);
case TypeCode.UInt16:
return ((ushort)0).Equals(o);
case TypeCode.Int32:
return 0.Equals(o);
case TypeCode.UInt32:
return 0.Equals(o);
case TypeCode.Int64:
return 0.Equals(o);
case TypeCode.UInt64:
return 0.Equals(o);
case TypeCode.Single:
return 0.Equals(o);
case TypeCode.Double:
return 0.Equals(o);
case TypeCode.Decimal:
return decimal.Zero.Equals(o);
case TypeCode.Char:
return ' '.Equals(o);
default:
return false;
}
}
return true;
}
public static ConstVal GetDefaultValue(ConstValKind kind)
{
switch (kind) {
case ConstValKind.Int:
return new ConstVal(s_zeroInt32);
case ConstValKind.Double:
return new ConstVal(0);
case ConstValKind.Long:
return new ConstVal(0);
case ConstValKind.Decimal:
return new ConstVal(decimal.Zero);
case ConstValKind.Float:
return new ConstVal(0);
case ConstValKind.Boolean:
return new ConstVal(s_false);
default:
return default(ConstVal);
}
}
public static ConstVal Get(bool value)
{
return new ConstVal(value ? s_true : s_false);
}
public static ConstVal Get(int value)
{
return new ConstVal((value == 0) ? s_zeroInt32 : ((object)value));
}
public static ConstVal Get(uint value)
{
return new ConstVal(value);
}
public static ConstVal Get(decimal value)
{
return new ConstVal(value);
}
public static ConstVal Get(string value)
{
return new ConstVal(value);
}
public static ConstVal Get(float value)
{
return new ConstVal(value);
}
public static ConstVal Get(double value)
{
return new ConstVal(value);
}
public static ConstVal Get(long value)
{
return new ConstVal(value);
}
public static ConstVal Get(ulong value)
{
return new ConstVal(value);
}
public static ConstVal Get(object p)
{
return new ConstVal(p);
}
}
}