使用通用约束与值类型
我正在试验流利的扩展方法。使用通用约束与值类型
我有以下简单的扩展方法来执行安全的强制转换。
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)” 。从错误消息我看到它是解决使用上面的方法,因为它是需要引用类型。
在.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;
由于ValueType是 - 尽管它的名称 - 实际上是一个类的类型,后一个公式需要装箱论据。不幸的是,我真的不认为有什么办法可以让.net允许基于泛型参数的值类型重载。 – supercat
什么的C#版本使用你正在用吗?在.NET 4中,选择了第二个重载。 –
你的意思是像'object o = 42; var i = o.As();'给出语法错误?或者你能显示给出它的确切代码吗? –
svick
@ svick的评论让我想起了你可能试图用数据库结果做的事情,比如DataRow。如果是这样,则已经有一个扩展方法来将行中的对象值转换为适当的类型。 [.Field](http://msdn.microsoft.com/en-us/library/bb360891.aspx) –