如何检查是否存在隐式或显式转换?

5

我有一个通用类,我希望强制类型参数的实例始终可以从字符串“转换/转化”。是否可以在不使用接口的情况下实现这一点?

可能的实现方式:

public class MyClass<T> where T : IConvertibleFrom<string>, new()
{
    public T DoSomethingWith(string s)
    {
        // ...
    }
}

理想的实现方式:

public class MyClass<T>
{
    public T DoSomethingWith(string s)
    {
        // CanBeConvertedFrom would return true if explicit or implicit cast exists
        if(!typeof(T).CanBeConvertedFrom(typeof(String))
        {
            throw new Exception();
        }
        // ...
    }
}

我更喜欢这种“理想”的实现方式,主要是为了不强制所有的 T 实现 IConvertibleFrom<> 接口。

3
一个能够对编程时错误使用运行时异常进行反应的实现方式有什么优点? - just somebody
1
如果你有一堆已经从字符串转换的类型,并且想要在新的类/方法中以我抽象描述的方式使用它们,那么这将是实现它的最省力的方法。去编辑每个类型并实现新接口将是一件麻烦的事情。 - Joaquim Rendeiro
3个回答

3

假设您想从sealed String类型转换,您可以忽略可能的可空性、装箱、引用和显式转换。仅op_Implicit()符合条件。更通用的方法由System.Linq.Expressions.Expression类提供:

using System.Linq.Expressions;
...
    public static T DoSomethingWith(string s)
    {
      var expr = Expression.Constant(s);
      var convert = Expression.Convert(expr, typeof(T));
      return (T)convert.Method.Invoke(null, new object[] { s });
    }

小心反射带来的代价。


我按原样采用了代码(但使用了通用方法DoSomethingWith<T>()),结果出现了NullReferenceException:get_Method返回null。 - Patrik

-1
if(!typeof(T).IsAssignableFrom(typeof(String))) {
    throw new Exception();
}

2
很遗憾,无论是在参数类型上声明隐式还是显式转换运算符都无法正常工作。 - Joaquim Rendeiro
嗯,我不确定我理解你在回复中的意思。如果T是一个整数,那么这段代码会抛出异常,但如果它是一个字符串或对象,则不会。这难道不是你想要的吗? - David Hedlund
1
我测试了下面的代码:class MyClass { public static implicit operator MyClass(string s) { return new MyClass(); } } typeof(MyClass).IsAssignableFrom(typeof(string))结果返回 false。我猜你期望它返回 true... - Joaquim Rendeiro

-2
为什么你不能像这样做呢?
public class MyClass<T> where T : string
{
    public T DoSomethingWith(string s)
    {
        // ...
    }
}

通过这种方式,您可以检查s是否可以在DoSomethingWith代码中转换为T。从那里,如果不能转换,您可以抛出异常,如果可以,则进行强制转换。

1
如果您明确声明泛型类型必须是字符串,为什么要使用泛型呢? - David Hedlund
我声明 T 必须派生自字符串,这并不意味着它必须是字符串。 - Graviton
1
不,我有自己的类型,可以从字符串转换而来。(附注:您不能继承自字符串)。 - Joaquim Rendeiro
1
"string" 是一个密封类型,无法编译。 - nawfal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接