我如何确定 Int32 实际上是可从 Int16 分配的
How do I determine Int32 is in fact assignable from Int16
我有几个 PropertyInfo
对象表示目标对象的属性。还有一组类似的 PropertyInfo
对象,表示源对象的属性。
如果名称和类型匹配,我的代码会将 属性 值从源分配给目标。但是有些类型是可分配的,但不是完全匹配的。其中一种情况是 Int16
类型的源 属性,但在目标端,同名的 属性 是 Int32
类型。我使用 targetProperty.Type.IsAssignableFrom(sourceProperty.Type).
所以换句话说,当我真的希望它给我一个 `true' 时,以下返回 false
typeof(Int32).IsAssignableFrom(typeof(Int16))
我已阅读其他主题,这些主题提示我 IsAssignableFrom 不是我需要的。在我开始编写长的 switch-case 代码之前,我正在检查是否有更简单的方法。
Int32 (int)
和 Int16 (short)
是结构。结构不允许继承。因此 IsAssignableFrom
不起作用,因为 short
没有继承自 int
。但是把一个short
赋给一个int
是没有问题的。
从 Int16
到 Int32
的隐式转换是 C# 语言功能,而不是 CLR 或 .NET 的功能,因此从技术上讲它们不是运行时可分配的(尽管,公平地说, IsAssignableFrom
会告诉你 object
可以从任何值类型分配,即使你在技术上需要装箱转换来完成它)。
除了像这样发出一个大的喇叭开关语句之外,我知道没有开箱即用的方法可以做到这一点:
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;
}
我有几个 PropertyInfo
对象表示目标对象的属性。还有一组类似的 PropertyInfo
对象,表示源对象的属性。
如果名称和类型匹配,我的代码会将 属性 值从源分配给目标。但是有些类型是可分配的,但不是完全匹配的。其中一种情况是 Int16
类型的源 属性,但在目标端,同名的 属性 是 Int32
类型。我使用 targetProperty.Type.IsAssignableFrom(sourceProperty.Type).
所以换句话说,当我真的希望它给我一个 `true' 时,以下返回 false
typeof(Int32).IsAssignableFrom(typeof(Int16))
我已阅读其他主题,这些主题提示我 IsAssignableFrom 不是我需要的。在我开始编写长的 switch-case 代码之前,我正在检查是否有更简单的方法。
Int32 (int)
和 Int16 (short)
是结构。结构不允许继承。因此 IsAssignableFrom
不起作用,因为 short
没有继承自 int
。但是把一个short
赋给一个int
是没有问题的。
从 Int16
到 Int32
的隐式转换是 C# 语言功能,而不是 CLR 或 .NET 的功能,因此从技术上讲它们不是运行时可分配的(尽管,公平地说, IsAssignableFrom
会告诉你 object
可以从任何值类型分配,即使你在技术上需要装箱转换来完成它)。
除了像这样发出一个大的喇叭开关语句之外,我知道没有开箱即用的方法可以做到这一点:
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;
}