什么是好处.Cast over。选择?

时间:2011-08-20 14:53:14

标签: c# linq

我有一个带有大多数基类型的隐式转换运算符的类型,并尝试在此类型的集合上使用.Cast<string>(),但失败了。当我挖掘它时,我注意到通过as进行的转换不会使用隐式或显式转换而只是不会编译,所以我猜这是.Cast落下的地方。所以这失败了

var enumerable = source.Cast<string>();

但这有效

var enumerable = source.Select(x => (string)x);

那么Cast的好处是什么?当然,这是几个字符较短,但似乎更有限。如果它可以用于转换,除了更紧凑的语法之外还有其他一些好处吗?

2 个答案:

答案 0 :(得分:42)

投射使用

当您的集合仅实现Cast(即非通用版本)时,IEnumerable的好处就出现了。在这种情况下,Cast会通过转换将所有元素转换为TResult,并返回IEnumerable<TResult>。这很方便,因为所有其他LINQ扩展方法(包括Select)仅针对IEnumerable<T>声明。在代码中,它看起来像这样:

IEnumerable source = // getting IEnumerable from somewhere

// Compile error, because Select is not defined for IEnumerable.
var results = source.Select(x => ((string)x).ToLower());

// This works, because Cast returns IEnumerable<string>
var results = source.Cast<string>().Select(x => x.ToLower());

CastOfType是为IEnumerable定义的唯一两个LINQ扩展方法。 OfType的工作方式与Cast类似,但会跳过不属于TResult类型的元素,而不是抛出异常。

投射和隐式转换

使用Cast隐式转化运算符无效的原因很简单:Castobject强制转换为TResult - 并且您的转化未定义为object,仅适用于您的特定类型。 Cast的实现是这样的:

foreach (object obj in source)
    yield return (TResult) obj;

强制执行转换的“失败”对应于基本转换规则 - 如此示例所示:

YourType x = new YourType(); // assume YourType defines an implicit conversion to string
object   o = x;

string bar = (string)x;      // Works, the implicit operator is hit.
string foo = (string)o;      // Fails, no implicit conversion between object and string

答案 1 :(得分:5)

我检查了Cast<TResult> IEnumerable,它是实现(非通用)ArrayList接口的类型的扩展方法。

它可以将未实现IEnumerable<T>的集合类(例如Select<T>)转换为可以执行的集合类,从而允许执行更丰富的操作(例如{{1}})它