更优雅的方法,找出我是否可以将值转换为某种类型

时间:2015-11-11 07:33:05

标签: c# reflection casting

我现在正在处理一些遗留代码,这些代码通常使用try + catchConvert.ToDecimal(someString)(例如)一起尝试将字符串转换为小数。出于某些原因,我必须使用这样的设置 - 在调试时 - 我停在每个抛出的异常(不仅是用户未处理的异常),所以这很烦人,我改变它以尽可能使用TryParse方法。

现在我处于object值和目标Type的情况下,我想知道的是我是否可以转换目标类型的值。现在这样做如下:

try
{
  Convert.ChangeType(val, targetType);
}
catch
{
  // Do something else
}

实际结果并不重要,不再使用。

虽然这段代码现在正在运行,但正如我所说的那样,它有点烦人,所以我想知道:是否有其他方法可以执行上述操作而无需捕获异常?

我在IsAssignableFrom上想到Type之类的内容,但这似乎并不适用于我的情况(我不想分配,我想知道如果可以明确转换。)

4 个答案:

答案 0 :(得分:3)

如果您的意思是强制转换,则可以使用is关键字:

object someObject = GetSomeObject();
if (someObject is string)
{
    ..
}

但请注意,该投射与Convert.ChangeType不一样。例如,您不能将字符串转换为int:

string numberString = "15";
int number = (int)numberString;

但你可以使用ChangeType

string numberString = "15";
int number = (int)Convert.ChangeType(numberString, typeof(int));

编辑:

如果您需要测试变量是否可以转换为特定类型,那么为什么不将try-catchConvert.ChangeType一起包装到测试方法中:

public bool IsConvertibleTo<T>(object value)
{
    try 
    {
        T convertedValue = (T)Convert.ChangeType(value, typeof(T));
        return true;
    }
    catch (InvalidCastException)
    {
        return false;
    }
    catch (FormatException)
    {
        return false;
    }
    catch (OverflowException)
    {
        return false;
    }
}

答案 1 :(得分:2)

我会给你一个解决方案&#34;隐藏&#34;例外。有时需要捕获异常并且正如您所说的那样烦人,因为调试器将在每个异常时停止。我知道,但有一种方法可以做到这一点:

[DebuggerStepThrough]
public bool CanChangeType(this object instance, Type targetType)
{
  try
  {
    Convert.ChangeType(val, targetType);
    return true;
  }
  catch
  {
    return false;
  }
}

技巧是DebuggerStepThrough - 属性。

但请记住,您永远无法调试到这样的方法。没有删除属性就没有错误修正。知道方法应该简短 - 非常短,显然应该没有任何错误。

我在Udp-classes上遇到同样的问题,在关闭时抛出异常。将此短代码提取到不包含错误的单独方法可以正常工作。

答案 2 :(得分:0)

如果您要查看val的类型,则应使用此类关键字is

if (val is targetType) {
    ...
}

如果您想将val转换为targetType类型,则应使用此类关键字as

targetType result = val as targetType;

if (result != null) {
    ...
}

他们两个都不会抛出异常!

链接:https://msdn.microsoft.com/zh-cn/library/cscsdfbt.aspx

答案 3 :(得分:0)

你最初的猜测是正确的。

<img src="/assets/images/halftone.png">

是按类型检查Convert.ChangeType是否有效的正确方法(如异常消息通常所示)。不确定为什么你反对这种方法,因为&#34;分配&#34;以它的名字命名。它只是对类型进行一些检查。除此之外,它实际上并没有进行任何分配。