标签: ienumerable

yield return仅适用于IEnumerable <T>?

yield return当返回类型是a IGrouping<TKey, TElement>还是IDictionary<TKey, TValue>?时,我可以使用吗?

.net c# ienumerable

31
推荐指数
3
解决办法
1万
查看次数

如何在C#中访问IEnumerable对象中的索引?

我有一个IEnumerable对象.我想基于索引访问例如:

for(i=0; i<=Model.Products; i++)
{
      ???
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?

c# ienumerable

30
推荐指数
4
解决办法
6万
查看次数

IEnumerable <T>.包含谓词

我只需要澄清给定的集合包含一个元素.

我可以做到这一点,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)

那么有没有其他方法可以使用谓词?

c# linq ienumerable predicate contains

30
推荐指数
3
解决办法
2万
查看次数

为什么Reverse for List和IEnumerable有两个完全不同的版本?

对于该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工作?

我对这种选择的历史原因非常感兴趣,而不是"怎么做"的东西!

c# linq ienumerable reverse list

29
推荐指数
2
解决办法
8630
查看次数

IEnumerable <T>作为返回类型

使用IEnumerable<T>返回类型有问题吗?FxCop抱怨返回List<T>(它建议返回Collection<T>).

好吧,我一直受到一条规则的指导:"尽可能接受,但要回报最大值".

从这个角度来看,返回IEnumerable<T>是一件坏事,但是当我想使用"懒惰检索"时我该怎么办?此外,yield关键字是如此的好.

c# collections ienumerable enumeration

28
推荐指数
3
解决办法
2万
查看次数

C#中的收益率是否是线程安全的?

我有以下代码:

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的影响?

c# ienumerable yield yield-return

26
推荐指数
3
解决办法
8769
查看次数

Resharper说我不应该使用List <T>

我有一个方法:

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>

c# resharper ienumerable list

26
推荐指数
1
解决办法
1531
查看次数

是否可以在不使用OrderBy的情况下将IEnumerable转换为IOrderedEnumerable?

假设有一种扩展方法可以根据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排序.

c# linq ienumerable iorderedenumerable

26
推荐指数
2
解决办法
7028
查看次数

将一个项添加到IEnumerable <T>的最佳方法是什么?

这是我如何将一个项添加到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对象?

c# ienumerable extension-methods

26
推荐指数
4
解决办法
6万
查看次数

为什么IEnumerator.Current的错误处理与IEnumerator <T> .Current不同?

我原本以为为实现的空集合执行以下代码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在以下任何条件下未定义:

  • 枚举器在创建枚举数之后立即定位在集合中的第一个元素之前.在读取Current的值之前,必须调用MoveNext以将枚举数推进到集合的第一个元素.
  • 对MoveNext的最后一次调用返回false,表示集合的结束.
  • 由于集合中所做的更改(例如添加,修改或删除元素),枚举器无效.

(我假设"未能抛出异常"可归类为"未定义行为"......)

但是,如果你做同样的事情,但使用一个IEnumerable,你会得到一个例外.此行为由文档IEnumerator.Current指定,其中指出:

  • 如果对MoveNext的最后一次调用返回false,则当前应该抛出InvalidOperationException,这表示集合的结束.

我的问题是:为什么会有这种差异?我不知道有一个很好的技术原因吗?

这意味着看起来相同的代码可以表现得非常不同,具体取决于它是否正在使用,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# ienumerable

26
推荐指数
1
解决办法
2490
查看次数