这更多是出于好奇而不是必要的问题,并且是由于必须处理 Active Directory (MS) 类型(例如 SearchResultCollection
(在 System.DirectoryServices
命名空间中))而产生的。
经常在代码中处理 AD 时,我发现我必须检查 null、Count、[0] 等值并转换我得到的值。同时希望底层 AD 对象通过COM 不会发生故障等。
最近玩了 Parallel.ForEach
之后 - 并且必须传递 IEnumerable<T>
,我想,也许看看如何将 SearchResultCollection
转换为我自己的自定义类型的 IEnumerable
会很有趣。在这种类型中,我将从 SearchResult
对象中提取所有值,并将它们粘贴到我自己的 .NET 托管代码中。然后我会删除 DirectoryEntry
、 DirectorySearcher
等。
因此,已经发现执行 searchResultCollection.Cast() 以便为 Parallel.ForEach 提供其源代码是个好主意,我添加了一个显式运算符来转换为我自己的类型(我们将其称为“Item
”) ')。
我在 ParallelForEach
、 var myItem = (Item)currentSearchResult
内对此进行了测试。
美好时光,我的 Actor 接线员被叫来,一切正常。然后我想,做类似 searchResultCollection.Cast<Item>()
的事情会很好。遗憾的是这不起作用,没有在强制转换运算符中遇到任何断点。
我做了一些谷歌搜索,发现了 Jon Skeet 回答过的一篇有用的帖子:
其关键在于,使用 .Select(...) 强制执行显式强制转换操作。好的,但是,嗯。
我离开并可能反汇编了 System.Core
-> System.Linq.Enumerable.Cast<TResult>
,我注意到这个“cast”实际上是在幕后进行“as”关键字转换:
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if (enumerable != null)
{
return enumerable;
}
if (source == null)
{
throw Error.ArgumentNull("source");
}
return CastIterator<TResult>(source);
}
我读了更多内容并发现了这个:
Implicit/Explicit conversion with respect to the "as" keyword
此处的最佳答案指出“as
”不会调用任何转换运算符..使用(强制转换)。从语义上讲,我觉得这有点奇怪,因为扩展方法称为强制转换。难道不应该强制转换吗?毫无疑问,这不会发生,这是有一个很好的理由,有人知道它是什么吗?
最佳答案
即使它使用强制转换运算符而不是 as
,它仍然不会调用用户定义的显式运算符,因此这并不重要。唯一的区别是抛出异常的类型。
运行时根本不知道显式运算符。根据 CLR,无法将搜索结果转换为 Item
。当编译器注意到存在与给定显式运算符匹配的强制转换时,它会在编译时注入(inject)对该显式运算符(基本上是静态方法)的调用到代码。一旦进入运行时,就不再了解转换的知识,只需调用一个方法来处理转换。
因为这就是显式运算符的实现方式,而不是向运行时提供如何进行转换的知识,所以 Cast
无法将显式运算符的调用注入(inject)到代码中。已经编译好了。编译时,不知道要注入(inject)任何显式运算符,因此没有注入(inject)任何内容。
关于c# - 转换为自定义类型、Enumerable.Cast<T> 和 as 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21607387/