更优雅的方式来确定我是否可以将一个值转换为某种类型

本文关键字:一个 转换 类型 种类 方式 是否 | 更新日期: 2023-09-27 18:21:31

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

现在我所处的情况是有一个object值和一个目标Type,我只想知道是否可以将该值转换为目标类型。现在这样做如下:

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

实际结果并不重要,也不会进一步使用。

正如我所说,虽然这段代码现在正在运行,但它有点烦人,所以我想知道:有没有其他方法可以在不捕获异常的情况下完成上述操作

我在Type上想到了类似IsAssignableFrom的东西,但这似乎不适用于我的情况(我不想赋值,我想知道是否可以显式转换)。

更优雅的方式来确定我是否可以将一个值转换为某种类型

如果你的意思是铸造,那么你可以使用is关键字,比如:

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

但请注意,casting和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;
    }
}

我将为您提供一个"隐藏"异常的解决方案。有时,捕获异常是必要的,正如您所说,这很烦人,因为调试器会在每个异常时停止。我知道,但有一种方法可以做到:

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

诀窍在于DebuggerStepThrough-属性。

但请记住,您永远无法调试到这样的方法中。如果不删除属性,就不会修复错误。知道一个方法应该很短——非常短,并且显然应该没有所有错误。

我对在关闭时抛出异常的Udp类也有同样的问题。将此短代码提取到一个不包含错误的单独方法中效果良好。

如果你想检查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

您最初的猜测是正确的。

    public static bool CanChangeType(Type type)
    {
        return typeof (IConvertible).IsAssignableFrom(type);
    }

是按类型检查Convert.ChangeType是否工作的正确方法(如异常消息通常所示)。不知道为什么你反对这个方法,因为它的名称中有"Assign"。它只是对类型进行一些检查。除此之外,它实际上不做任何分配。

相关文章: