読者です 読者をやめる 読者になる 読者になる

.NET for Metro Style AppsにSystem.TypeCodeが存在しないので代替処理を書いてみた

WinRT

Mono.CecilやIronyをMetro Style Apps用に移植してみたりしているのだけど、結構System.TypeCodeを使っている箇所があって、書き換えがめんどくさかった。
なので、TypeCode関係を移植とは言わないまでも、移植するためのコードを書いてみた。

enum TypeCode

/// <summary>
/// Specifies the type of an object.
/// </summary>
public enum TypeCode
{
    /// <summary>
    /// A null reference.
    /// </summary>
    Empty,

    /// <summary>
    /// A general type representing any reference or value type not explicitly represented
    /// by another TypeCode.
    /// </summary>
    Object,

    /// <summary>
    /// A database null (column) value.
    /// </summary>
    DBNull,

    /// <summary>
    /// A simple type representing Boolean values of true or false.
    /// </summary>
    Boolean,

    /// <summary>
    /// An integral type representing unsigned 16-bit integers with values between 0 and 65535.
    /// The set of possible values for the Char type corresponds to the Unicode character set.
    /// </summary>
    Char,

    /// <summary>
    /// An integral type representing signed 8-bit integers with values between -128 and 127.
    /// </summary>
    SByte,

    /// <summary>
    /// An integral type representing unsigned 8-bit integers with values between 0 and 255.
    /// </summary>
    Byte,

    /// <summary>
    /// An integral type representing signed 16-bit integers with values between -32768 and 32767.
    /// </summary>
    Int16,

    /// <summary>
    /// An integral type representing unsigned 16-bit integers with values between 0 and 65535.
    /// </summary>
    UInt16,

    /// <summary>
    /// An integral type representing signed 32-bit integers with values between -2147483648 and 2147483647.
    /// </summary>
    Int32,

    /// <summary>
    /// An integral type representing unsigned 32-bit integers with values between 0 and 4294967295.
    /// </summary>
    UInt32,

    /// <summary>
    /// An integral type representing signed 64-bit integers with values between
    /// -9223372036854775808 and 9223372036854775807.
    /// </summary>
    Int64,

    /// <summary>
    /// An integral type representing unsigned 64-bit integers with values between
    /// 0 and 18446744073709551615.
    /// </summary>
    UInt64,

    /// <summary>
    /// A floating point type representing values ranging from approximately
    /// 1.5 x 10 -45 to 3.4 x 10 38 with a precision of 7 digits.
    /// </summary>
    Single,

    /// <summary>
    /// A floating point type representing values ranging from approximately
    /// 5.0 x 10 -324 to 1.7 x 10 308 with a precision of 15-16 digits.
    /// </summary>
    Double,

    /// <summary>
    /// A simple type representing values ranging from 1.0 x 10 -28 to approximately
    /// 7.9 x 10 28 with 28-29 significant digits.
    /// </summary>
    Decimal,

    /// <summary>
    /// A type representing a date and time value.
    /// </summary>
    DateTime,

    /// <summary>
    /// A sealed class type representing Unicode character strings.
    /// </summary>
    String
}

TypeCodeExtensions

public static class TypeCodeExtensions
{
    private static readonly Dictionary<Type, TypeCode> TypeCodeTable = new Dictionary<Type,TypeCode>();

    static TypeCodeExtensions()
    {
        TypeCodeTable[typeof(bool)] = TypeCode.Boolean;
        TypeCodeTable[typeof(char)] = TypeCode.Char;
        TypeCodeTable[typeof(sbyte)] = TypeCode.SByte;
        TypeCodeTable[typeof(byte)] = TypeCode.Byte;
        TypeCodeTable[typeof(short)] = TypeCode.Int16;
        TypeCodeTable[typeof(ushort)] = TypeCode.UInt16;
        TypeCodeTable[typeof(int)] = TypeCode.Int32;
        TypeCodeTable[typeof(uint)] = TypeCode.UInt32;
        TypeCodeTable[typeof(long)] = TypeCode.Int64;
        TypeCodeTable[typeof(ulong)] = TypeCode.UInt64;
        TypeCodeTable[typeof(float)] = TypeCode.Single;
        TypeCodeTable[typeof(double)] = TypeCode.Double;
        TypeCodeTable[typeof(decimal)] = TypeCode.Decimal;
        TypeCodeTable[typeof(DateTime)] = TypeCode.DateTime;
        TypeCodeTable[typeof(string)] = TypeCode.String;
    }
        
    /// <summary>
    /// Converts the underlying type code of the specified Type.
    /// </summary>
    /// <param name="type">The type whose underlying type code to get. </param>
    /// <returns>The code of the underlying type.</returns>
    public static TypeCode AsTypeCode(this Type type)
    {
        if (TypeCodeTable.ContainsKey(type))
        {
            return TypeCodeTable[type];
        }
            
        if (type.GetTypeInfo().IsEnum)
        {
            return TypeCodeTable[Enum.GetUnderlyingType(type)];
        }
            
        return TypeCode.Object;
    }
}

Type#GetTypeCode()にenumを食わせるとInt32(正確にはenum宣言時に指定した型)を返してくるのは知らんかったので、ちょっと勉強になった。