什么';这是的好处.铸造.选择
本文关键字:铸造 选择 什么 | 更新日期: 2023-09-27 18:06:17
我有一个类型,它具有对大多数基类型的隐式转换运算符,并尝试在该类型的集合上使用.Cast<string>()
,但失败了。在深入研究的过程中,我注意到通过as
进行的强制转换不使用隐式或显式转换,只是不会编译,所以我想这就是.Cast
失败的地方。所以失败了
var enumerable = source.Cast<string>();
但这对有效
var enumerable = source.Select(x => (string)x);
那么Cast的好处是什么呢?当然,它缩短了几个字符,但似乎更有限。如果它可以用于转换,除了更紧凑的语法之外,还有其他好处吗?
铸件用法
当您的集合只实现IEnumerable
(即不实现通用版本(时,Cast
的好处就来了。在这种情况下,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());
CCD_ 11和CCD_ 12是为CCD_ 13定义的仅有的两种LINQ扩展方法。OfType
的工作方式与Cast
类似,但跳过不属于TResult
类型的元素,而不是抛出异常。
强制转换和隐式转换
使用Cast
时,隐式转换运算符不起作用的原因很简单:Cast
将object
强制转换为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
我在MSDN页面上查看了Cast<TResult>
,它是实现(非通用(IEnumerable
接口的类型的扩展方法。
它可以将不实现IEnumerable<T>
的集合类(如ArrayList
(转换为实现CCD_25的集合类,从而允许对其执行更丰富的操作(如CCD27(。
而且Cast
要快得多。我为(string)
铸造编写了一个基准:
object[] arr = new[] { "123", "123", "123" ... }; //total 30 elements
方法 | 平均值 | 错误 | StdDev | Gen0 | 分配|
---|---|---|---|---|---|
选择 | 21.182 ns | 1.8182 ns | 0.0997 ns | 0.0076 | 48 B |
铸造 | 3.791 ns | 0.4695 ns | 0.0257 ns | - | - |