假设我有以下愿望,以简化IConvertible以允许我通过使用泛型类型参数来调用它们。我计划通过创建泛型Converter并将它们存储在静态泛型类的静态属性上来实现。以下是生成委托::
的代码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);
}
}
顺便说一句,添加对Enum的支持有一个小的副作用,因为它们从IConvertible继承而且显然从UnderylingType到Enum的转换是隐式的,因此只需要委托的返回类型。
现在,困难的部分已经完成,我想添加我的扩展方法:
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 :(得分:0)
很抱歉,您不允许在尖括号内使用可以为空的类型,但这是不允许的。我知道这很蹩脚,但它今天的编译工作方式。你不能在那里放置一个具体的可空类型,例如“bool?”
这要求您更改方法名称或添加一些参数。对不起我知道这不是你在哪里跳,但它不容易绕过编译器本身。因此,您的ToNullable解决方案与任何解决方案一样好。
答案 1 :(得分:0)
您的ToNullable<T>
解决方法是您最接近的。即使 是您想要的语法,也不允许方法签名 仅因通用约束而不同。