yield return当返回类型是a IGrouping<TKey, TElement>还是IDictionary<TKey, TValue>?时,我可以使用吗?
我有一个IEnumerable对象.我想基于索引访问例如:
for(i=0; i<=Model.Products; i++)
{
???
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?
我只需要澄清给定的集合包含一个元素.
我可以做到这一点,collection.Count(foo => foo.Bar == "Bar") > 0)但它会做不必要的工作 - 迭代整个集合,而我需要在第一次出现时停止.
但我想尝试使用Contains()谓词,例如foo => foo.Bar == "Bar".
目前IEnumerable<T>.Contains有两个签名:
IEnumerable<T>.Contains(T)
IEnumerable<T>.Contains(T, IEqualityComparer<T>)
所以我必须指定一些变量来检查:
var collection = new List<Foo>() { foo, bar };
collection.Contains(foo);
Run Code Online (Sandbox Code Playgroud)
或写我IEqualityComparer<Foo>将用于反对我的收藏的自定义:
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo f1, Foo f2)
{
return (f1.Bar == f2.Bar); // my predicate
}
public int GetHashCode(Foo f)
{
return f.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
那么有没有其他方法可以使用谓词?
对于该List对象,我们有一个名为Reverse()的方法.
它反转了"就地"列表的顺序,它不会返回任何内容.
对于该IEnumerable对象,我们有一个名为Reverse()的扩展方法.
它返回另一个IEnumerable.
我需要在列表中以相反的顺序迭代,所以我不能直接使用第二种方法,因为我得到一个List,我不想反转它,只是向后迭代.
所以我可以这样做:
for(int i = list.Count - 1; i >=0; i--)
Run Code Online (Sandbox Code Playgroud)
要么
foreach(var item in list.AsEnumerable().Reverse())
Run Code Online (Sandbox Code Playgroud)
我发现它的可读性低于我拥有IEnumerable时的可读性
foreach(var item in list.Reverse())
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么这两种方法以这种方式实现,具有相同的名称.这很令人讨厌和困惑.
为什么没有一个名为BackwardsIterator()的扩展名在Reverse()的地方为所有IEnumerable工作?
我对这种选择的历史原因非常感兴趣,而不是"怎么做"的东西!
使用IEnumerable<T>返回类型有问题吗?FxCop抱怨返回List<T>(它建议返回Collection<T>).
好吧,我一直受到一条规则的指导:"尽可能接受,但要回报最大值".
从这个角度来看,返回IEnumerable<T>是一件坏事,但是当我想使用"懒惰检索"时我该怎么办?此外,yield关键字是如此的好.
我有以下代码:
private Dictionary<object, object> items = new Dictionary<object, object>;
public IEnumerable<object> Keys
{
get
{
foreach (object key in items.Keys)
{
yield return key;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是线程安全的吗?如果不是我必须lock围绕循环或yield return?
这就是我的意思:
KeysThread1 访问属性,而Thread2将一个项添加到基础字典.Thread1是否受Thread2的影响?
我有一个方法:
static void FileChangesDetected(List<ChangedFiles> files)
Run Code Online (Sandbox Code Playgroud)
我使用Visual Studio 2010和Resharper.Resharper总是建议我更改List<T>为IEnumerable<T>,我想知道为什么会这样.
在方法中,我只是这样做:
foreach (var file in files)
{ ... }
Run Code Online (Sandbox Code Playgroud)
是否有使用IEnumerable<T>而不是List<T>?
假设有一种扩展方法可以根据SortMethod枚举指定的几种类型的排序(即按各种属性排序)来订购IQueryable .
public static IOrderedEnumerable<AClass> OrderByX(this IQueryable<AClass> values,
SortMethod? sortMethod)
{
IOrderedEnumerable<AClass> queryRes = null;
switch (sortMethod)
{
case SortMethod.Method1:
queryRes = values.OrderBy(a => a.Property1);
break;
case SortMethod.Method2:
queryRes = values.OrderBy(a => a.Property2);
break;
case null:
queryRes = values.OrderBy(a => a.DefaultProperty);
break;
default:
queryRes = values.OrderBy(a => a.DefaultProperty);
break;
}
return queryRes;
}
Run Code Online (Sandbox Code Playgroud)
在sortMethodis 的情况下null(即指定我不关心值的顺序),是否有一种方法来代替通过某个默认属性排序,而只是将IEnumerator值传递为"有序"而不是必须执行实际排序?
我希望能够调用此扩展,然后可能执行一些额外的ThenBy排序.
这是我如何将一个项添加到IEnumerable对象:
//Some IEnumerable<T> object
IEnumerable<string> arr = new string[] { "ABC", "DEF", "GHI" };
//Add one item
arr = arr.Concat(new string[] { "JKL" });
Run Code Online (Sandbox Code Playgroud)
这很尴尬.但是,我没有看到类似的方法ConcatSingle().
有没有更简洁的方法将单个项添加到IEnumerable对象?
我原本以为为实现的空集合执行以下代码IEnumerable<T>会抛出异常:
var enumerator = collection.GetEnumerator();
enumerator.MoveNext();
var type = enumerator.Current.GetType(); // Surely should throw?
Run Code Online (Sandbox Code Playgroud)
因为集合是空的,所以访问IEnumerator.Current无效,我本来期望一个例外.但是,没有例外List<T>.
这是允许的文档IEnumerator<T>.Current,其中指出Current在以下任何条件下未定义:
(我假设"未能抛出异常"可归类为"未定义行为"......)
但是,如果你做同样的事情,但使用一个IEnumerable,你会得到一个例外.此行为由文档IEnumerator.Current指定,其中指出:
我的问题是:为什么会有这种差异?我不知道有一个很好的技术原因吗?
这意味着看起来相同的代码可以表现得非常不同,具体取决于它是否正在使用,IEnumerable<T>或者IEnumerable如下面的程序所示(注意代码内部showElementType1()和showElementType1()相同):
using System;
using System.Collections;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
public static void Main()
{
var list = new List<int>();
showElementType1(list); // Does not throw an exception.
showElementType2(list); // Throws …Run Code Online (Sandbox Code Playgroud) c# ×10
ienumerable ×10
linq ×3
list ×2
.net ×1
collections ×1
contains ×1
enumeration ×1
predicate ×1
resharper ×1
reverse ×1
yield ×1
yield-return ×1