【问题标题】:Checking if a type supports an implicit or explicit type conversion to another type with .NET使用 .NET 检查一个类型是否支持隐式或显式类型转换为另一种类型
【发布时间】:2010-09-05 17:49:47
【问题描述】:

假设您已经获得了两个 System.Type,并且您想确定是否存在从一个到另一个的隐式或显式类型转换。

在没有专门检查静态方法的情况下,是否有内置方法来确定该类型是否支持其中一种或这些转换?

我知道这是一个简短的问题,但我认为这个场景相对容易解释,如果不是,请告诉我。

提前致谢, 斯蒂芬。

【问题讨论】:

标签: c# reflection type-conversion


【解决方案1】:

Expression.Convert 可以查找用户定义的转换运算符,但不幸的是,如果没有找到它只会抛出异常。你可以这样使用它:

public static bool CanConvert(Type fromType, Type toType)
{
    try
    {
        // Throws an exception if there is no conversion from fromType to toType
        Expression.Convert(Expression.Parameter(fromType, null), toType);
        return true;
    }
    catch
    {
        return false;
    }
}

【讨论】:

  • 感谢 Quartermeister,这绝对是一个解决方案!
  • @meandmycode:如果你想在没有异常开销的情况下实现相同的东西,你可以在 Expression.Convert 上运行 Reflector 来看看它到底做了什么。有趣的方法是 System.Dynamic.Utils.TypeUtils 中的 HasIdentityPrimitiveOrNullableConversion、HasReferenceConversion 和 GetUserDefinedCoercionMethod。
  • 很好,感谢您的研究工作,我并不完全反对避免使用您建议的代码,即使我实现了 TypeUtils 之类的方法,它最终可能会比维护它更多的工作只捕获异常。
【解决方案2】:

我不这么认为。您将使用反射并在每种类型上寻找那些好的 ol' op_Implicitop_Explicit 静态方法。

这带来了一个非常有趣的问题:哪个对性能有更大的影响,反射(这个答案)还是使用控制流异常Quartermeister's)?老实说,我猜不出来。您可能想对每个人进行概要分析并自己找出答案。

【讨论】:

  • Eep,也许这不是一件坏事,我担心寻找这些特殊命名的方法很脆弱,但另一方面我永远不会期望这些方法名称会改变!
  • @meandmycode:是的,我不确定它们是否真的被指定了;但我认为它们与get_set_ 属性方法属于同一类别——非常不太可能改变(尽管我与您一样对这种“幕后”方法感到不安)。
  • 我不是 100% 肯定,但接近 :) 如果您只是在寻找这些方法(例如 int 到 long 并派生到 base/interface),我认为您会错过一些内置转换. Shich 会增加解决方案的脆弱性,因为除了更改方法名称之外的其他更改将是一个重大更改
  • @Rune FS:是的——我的意思是建议这些必须包含在 OP 的代码中,而不是这可以被视为完整的解决方案。
  • 这个解决方案确实有效,我简要地写了它,它不包括一些内置的原始类型转换,但这并不难补救,我的解决方案到目前为止看起来像这:返回类型.HasPrimitiveConversionTo(targetType) || type.HasImplicitConversionTo(targetType) || type.HasExplicitConversionTo(targetType);
【解决方案3】:

您可以尝试将每个转换为另一个并捕获异常

【讨论】:

  • 不幸的是,我只能访问 Type 对象,而不是实际的对象本身,所以我无法做到这一点。
【解决方案4】:

我认为Type.IsAssignableFrom 应该可以满足您的需求。

[edit] 请注意,这不考虑转换运算符,因此这可能对您没有用处。无论如何都值得一提。

【讨论】:

  • 这不会考虑任何自定义转换运算符。它只查看类型层次结构。
  • 我不确定这是否处理您可以使用 C# 定义的隐式/显式类型转换运算符。例如,如果我写 typeof(XName).IsAssignableFrom(typeof(string)) 我得到错误。但是 XName 确实有从字符串的隐式类型转换。
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 2011-03-02
  • 2013-07-14
  • 2012-03-28
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多