c# - 对值类型使用通用约束

标签 c# generics extension-methods constraints fluent-interface

我正在试验流畅的扩展方法。

我有以下简单的扩展方法来执行安全转换。

     public static T As<T>(this Object source)
         where T : class
     {
         return source as T;
     }

这很好用,但是当我试图使使用带有重载的值类型变得直观时

     public static T As<T>(this ValueType source)
         where T : struct
     {
         return (T)source;
     }

我遇到了问题。方法解析逻辑总是选择上面的第一个方法,并给出一个语法错误(准确地说)该结构不是一个类。

有没有办法处理上述问题,或者我应该在用相同的方法测试和处理所有类型的同时移除约束?

====编辑:回答问题====

我正在针对 3.5 框架进行编译。我并不是真的想完成任何特别的事情;这只是上面的实验。我的兴趣被激起了,我拼凑了一些代码。

我并不特别担心它仍然是一个“安全”类型转换。这就是它的开始方式,并且可以使用 default() 保持安全——但这并不是问题的真正焦点,确保“安全”的代码只会变得模糊不清。

至于表现力,没有value.As<int>()不比 (int)value 更具表现力;但是为什么该方法的用户必须“只知道”它只适用于引用类型呢?我尝试使用它更多地是关于方法的预期行为,而不是表达性写作。

代码片段value.As<DateTime>() ,给出错误“类型‘System.DateTime’必须是引用类型才能将其用作泛型类型或方法中的参数‘T’....As(object)”。从错误消息中我看到它正在解决使用上面的 top 方法,因为它需要引用类型。

最佳答案

在 .NET 4 中,第二个重载是根据您的代码示例选择的。 (也刚刚针对 .NET 3.5 进行了测试,结果相同。)

int myInt = 1;
long myLong = myInt.As<long>(); // chooses ValueType version

但是,这只会让我们到达下一次崩溃的现场。 (T)source; 导致无效的转换异常。您可以通过将方法编写为

来解决这个问题
public static T As<T>(this ValueType source)
    where T : struct
{
    return (T)Convert.ChangeType(source, typeof(T));
}

但是,我想知道您实际上想要实现什么,因为我看不到直接的好处。 (就此而言,这不像 source as T 对象版本那样安全。)例如,

long myLong = myInt.As<long>();

任何比

更具表现力或更易于使用的
long myLong = (long)myInt;

关于c# - 对值类型使用通用约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676502/

相关文章:

c# - 十进制值到字符串

swift - 如何调用具有与此类同名函数的类的静态方法?

c# - 优化通用 AddDistinct 扩展方法

c# - 如何使用新的输入系统访问点击(桌面)/点击(移动)位置?

c# - 如何让nuget在项目中创建文件夹?

c# - 在 C# 中模拟基数分配有多接近

java - 创建 hashmap 时正确使用泛型

java - Spring Boot @ConditionalOnMissingBean 和泛型类型

java - 根据成员变量或映射函数返回子列表

asp.net-mvc-3 - MVC 扩展方法错误