c# - 转换为自定义类型、Enumerable.Cast<T> 和 as 关键字

标签 c# linq casting ienumerable explicit-conversion

这更多是出于好奇而不是必要的问题,并且是由于必须处理 Active Directory (MS) 类型(例如 SearchResultCollection(在 System.DirectoryServices 命名空间中))而产生的。

经常在代码中处理 AD 时,我发现我必须检查 null、Count、[0] 等值并转换我得到的值。同时希望底层 AD 对象通过COM 不会发生故障等。

最近玩了 Parallel.ForEach 之后 - 并且必须传递 IEnumerable<T> ,我想,也许看看如何将 SearchResultCollection 转换为我自己的自定义类型的 IEnumerable 会很有趣。在这种类型中,我将从 SearchResult 对象中提取所有值,并将它们粘贴到我自己的 .NET 托管代码中。然后我会删除 DirectoryEntryDirectorySearcher 等。

因此,已经发现执行 searchResultCollection.Cast() 以便为 Parallel.ForEach 提供其源代码是个好主意,我添加了一个显式运算符来转换为我自己的类型(我们将其称为“Item”) ')。

我在 ParallelForEachvar myItem = (Item)currentSearchResult 内对此进行了测试。

美好时光,我的 Actor 接线员被叫来,一切正常。然后我想,做类似 searchResultCollection.Cast<Item>() 的事情会很好。遗憾的是这不起作用,没有在强制转换运算符中遇到任何断点。

我做了一些谷歌搜索,发现了 Jon Skeet 回答过的一篇有用的帖子:

IEnumerable.Cast<>

其关键在于,使用 .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/

相关文章:

c# - 重构别人源码的礼仪?

c# - 为什么使用匿名类型有效而使用不在 GroupBy 中的显式类型?

c# - 在签名程序集的内部接口(interface)上使用 Moq 的 TypeLoadException

c# - 为 gridview 提供一种在所有系统中都不存在的字体

c# - 根据另一个数组中指定的索引从数组中选择元素c#

c# - 合并 2 个 LINQ 查询

interface - Golang : Can I cast to chan interface{}

c++ - 不完整的类 : Convert void* to pointer to class type via dynamic_cast

android - 无法转换为 java.lang.Long Android SharedPreferences

c# - 有没有办法只返回不使用 LINQ 抛出异常的函数调用?