Effective C# 学习笔记(三十九) 使用Dynamic处理范型参数的运行时类型
2011-07-29 19:35 小郝(Kaibo Hao) 阅读(387) 评论(0) 编辑 收藏 举报由于Enumerable.Cast<T>方法,其对T类型所知范围仅限于Sytem.Object类型的那些方法,所以对于T类型的特殊类型转换方法(无论是Implicit还是Explicit的)其都不会理睬。所以在使用运行时类型枚举转换时请注意使用适当的方法。
先看一段代码:
public class MyType
{
public String StringMember { get; set; }
//隐式转换为String类型的定义
public static implicit operator String(MyType aString)
{
return aString.StringMember;
}
//从String类型转换为MyType类型的定义
public static implicit operator MyType(String aString)
{
return new MyType { StringMember = aString };
}
}
var answer1 = GetSomeStrings().Cast<MyType>();
try
{
foreach (var v in answer1)
Console.WriteLine(v);
}
catch (InvalidCastException)
{
Console.WriteLine("Cast Failed!");
}
上面的代码会抛出InvalidCastException异常,因为Cast<T>方法并不认识MyType的那些隐式类型转换转换方法,所以自然抛出异常。
var answer3 = from v in GetSomeStrings()
select (MyType)v;
foreach (var v in answer3)
Console.WriteLine(v);
上面的代码可以成功,因为其使用了Reference conversion类型转换。
有两种转换可以使隐式或显示类型转换起作用:
Reference conversion :当 is 操作成功时
Boxing conversion:装箱操作,将值类型转换为引用类型
你也可以这样写:
var answer4 = GetSomeStrings().Select(n => new MyType { StringMember = n });
var answer5 = from v in GetSomeStrings()
select new MyType { StringMember = v };
这样的话你可能需要为每一个集合枚举的遍历进行类型转换,其实大可不必。我们可以写一个通用的Convert<T>扩展方法,其实现逻辑如下:
public static IEnumerable<TResult> Convert<TResult>( this System.Collections.IEnumerable sequence)
{
foreach (object item in sequence)
{
dynamic coercion = (dynamic)item;
yield return (TResult)coercion;
}
}
在使用的时候我们可以这样:
var convertedSequence = GetSomeStrings().Convert<MyType>();
出处:http://www.cnblogs.com/haokaibo/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。