IEnumerable和OrderBy的奇怪之处

问题描述

我有一段看似简单的代码,但似乎并非如此。

// Enum values
IEnumerable values = Enum.GetValues(typeof(TVal)).Cast<TVal>();

// Sort them by alpha
if (sortByAlpha)
{
    values = (values).OrderBy(i => i.ToString());
}

如果我写:

// Get enum values
IEnumerable values = Enum.GetValues(typeof(TVal)).Cast<TVal>();

// Sort them by alpha
if (sortByAlpha)
{
    values = Enum.GetValues(typeof(TVal)).Cast<TVal>().OrderBy(i => i.ToString());
}

有效。

为什么?第一段代码中的值应该相同吗? 我没看到什么? 在.Net 4.5.1上运行此

解决方法

由于OrderByIEnumerable<T>的扩展方法,因此您无法使用IEnumerable

因此,为了使其能够编译,请更改您的第一个代码段并执行以下操作:

IEnumerable<TVal> values = Enum.GetValues(typeof(TVal)).Cast<TVal>();

// Sort them by alpha
if (sortByAlpha)
{
     values = values.OrderBy(i => i.ToString());
 }

IEnumerableIEnumerable<T>之间的区别在于,后者基本上是一个更专业的版本,知道其处理哪些元素。

例如,多数民众赞成在Cast方法中所做的事情,它将非特定的IEnumerable变成IEnumerable<T>,使您可以在第二个示例中使用该OrderBy。

我建议您对此主题进行一些搜索。

,

其他答复已经很好地解释了错误的原因,但是我想澄清一下代码中错误的原因。要开始,这里是您的代码:

// Enum values
IEnumerable values = Enum.GetValues(typeof(TVal)).Cast<TVal>();
//   ^---- This is where it's going wrong

// Sort them by alpha
if (sortByAlpha)
{
    values = (values).OrderBy(i => i.ToString());
}

Cast<TVal>()返回一个IEnumerable<TVal>,但是由于您将其另存为IEnumerable,因此隐式转换了它。类似于:

IEnumerable values = (IEnumerable) Enum.GetValues(typeof(TVal)).Cast<TVal>();

这是完全有效的,因为IEnumerable<T>继承自IEnumerable,因此强制转换有效,但是您会失去IEnumerable<T>IEnumerable上提供的所有功能。其中之一是OrderBy方法。