2010-10-07 37 views
0

让我说我有以下愿望,以简化IConvertible的允许我通过使用泛型类型参数调用它们。我打算通过创建通用转换器并将它们存储在静态泛型类的静态属性上来实现此目的。这里是产生代表::我该如何做一个可空类型的构造函数?

static class IConvertibleHelper<T> where T : struct, IConvertible 
{ 
    public static readonly Converter<IConvertible, T> Converter; 
    public static readonly Converter<IConvertible, T?> NullableConverter; 
    static IConvertibleHelper() 
    { 
     Type type = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T); 
     Converter = Delegate.CreateDelegate(typeof(Converter<IConvertible, T>), typeof(Convert).GetMethod("To" + type.Name,new Type[]{typeof(object)})) as Converter<IConvertible, T>; 
     NullableConverter = obj => obj == null ? default(T?) : (T?)Converter(obj); 
    } 
} 

作为旁的代码,有增加对枚举的支撑件的一个小的副作用,因为它们从IConvertible继承,显然从UnderylingType到枚举转换是隐式的,因此只有委托的返回类型需要。

现在,最困难的部分是做,我想补充我的扩展方法:

public static class IConvertibleHelper 
{ 
    public static T To<T>(this IConvertible convertible) where T:struct,IConvertible 
    { 
    return IConvertibleHelper<T>.Converter(convertible); 
    } 
    public static T? To<T?>(this IConvertible convertible) where T : struct, IConvertible 
    { 
     return IConvertibleHelper<T>.NullableConverter(convertible); 
    } 
} 

第扩展方法是好的,甚至作品! 第二个扩展根本不编译。我可以左右使用以下,而跛脚的工作:

public static T? ToNullable<T>(this IConvertible convertible) where T : struct, IConvertible 
{ 
    return IConvertibleHelper<T>.NullableConverter(convertible); 
} 

但后来我们坚持要求调用不同的签名转换为空值类型。 一个更差的解决方法(出于可用性原因,imo),是使用out或ref参数作为返回,以及右边两个方法。这在技术上允许发生类型推断魔法,但是使得调用这个简单的小扩展方法更烦人。

回答

0

很抱歉地说你不允许在尖括号内有一个可以为null的类型,但它是不允许的。我知道这是蹩脚的,但它是如何编译今天的作品。你不能在那里放置一个具体的可空类型,比如“bool?”

这需要您更改方法名称或添加一些参数。对不起,我知道这不是你跳槽的地方,但它不容易绕过编译器本身。因此,您的ToNullable解决方案与其他任何解决方案一样好。

+1

尽管在尖括号中不允许使用'bool?',但扩展形式为'可空'。所以你可以有'到>'。 – 2010-10-07 04:57:58

+0

@Bradley您可能想要测试,因为尖括号内的可空不能编译。据我所知,你不能嵌套泛型声明。迈克尔所做的解决方法是解决他的问题的唯一真正的工作。 – 2010-10-07 17:18:52

0

您的ToNullable<T>解决方法是最接近你会得到的。即使是您所需的语法,但方法签名不允许仅因通用约束而不同。

相关问题