简体   繁体   中英

How do I determine Int32 is in fact assignable from Int16

I have a several PropertyInfo objects that represent properties of a target object. And a similar set of PropertyInfo objects that represent the properties of a source object.

My code assigns property values from source to target if the name and type matches. But some of the types are assignable but not exact match. One of the cases is source property of type Int16 but on target side the property of same name is of type Int32 . I use the targetProperty.Type.IsAssignableFrom(sourceProperty.Type) .

So in other words, the following is returning false while I really want it to give me a `true'

typeof(Int32).IsAssignableFrom(typeof(Int16))

I have read other threads which suggest me that IsAssignableFrom is not what I need. Before I jump on to write a long switch-case code, I am checking to see if there is any easier way.

Implicit conversion from Int16 to Int32 is a C# language feature, not a feature of the CLR or .NET, so they're not technically runtime assignable (although, to be fair, IsAssignableFrom would tell you that object is assignable from any value type even though you technically need a boxing conversion to do it).

There's no out of the box way I know to do this besides making a big honking switch statement like this:

public static bool HasImplicitConversion( Type source, Type destination )
{
    var sourceCode = Type.GetTypeCode( source );
    var destinationCode = Type.GetTypeCode( destination );
    switch( sourceCode )
    {
        case TypeCode.SByte:
            switch( destinationCode )
            {
                case TypeCode.Int16:
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Byte:
            switch( destinationCode )
            {
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Int16:
            switch( destinationCode )
            {
                case TypeCode.Int32:
                case TypeCode.Int64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.UInt16:
            switch( destinationCode )
            {
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Int32:
            switch( destinationCode )
            {
                case TypeCode.Int64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.UInt32:
            switch( destinationCode )
            {
                case TypeCode.UInt32:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Int64:
        case TypeCode.UInt64:
            switch( destinationCode )
            {
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Char:
            switch( destinationCode )
            {
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                case TypeCode.Decimal:
                    return true;
            }
            return false;
        case TypeCode.Single:
            return ( destinationCode == TypeCode.Double );
    }
    return false;
}

Int32 (int) and Int16 (short) are Structs. Structs does not allow inheritances. Therefore IsAssignableFrom does not work because short does not inherit from int . But there is no problem in assigning a short to an int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM