相关疑难解决方法(0)

Resharper的示例代码,用于解释"可能多次枚举IEnumerable"

有时Resharper会警告:

可能的多个枚举IEnumerable

关于如何处理这个问题还有一个问题,ReSharper网站也在这里解释了一些事情.它有一些示例代码,告诉您这样做:

IEnumerable<string> names = GetNames().ToList();
Run Code Online (Sandbox Code Playgroud)

我的问题是关于这个特定的建议:这不会导致在2 for-each循环中两次枚举集合吗?

c# resharper resharper-7.1

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

为什么通用ICollection不在.NET 4.5中实现IReadOnlyCollection?

在.NET 4.5/C#5中,IReadOnlyCollection<T>使用Count属性声明:

public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable
{
    int Count { get; }
}
Run Code Online (Sandbox Code Playgroud)

我想知道,ICollection<T>实现IReadOnlyCollection<T>接口也没有意义:

public interface ICollection<T> : IEnumerable<T>, IEnumerable, *IReadOnlyCollection<T>*
Run Code Online (Sandbox Code Playgroud)

这意味着实现的类ICollection<T>将自动实现IReadOnlyCollection<T>.这对我来说听起来很合理.

ICollection<T>抽象可以被看作是所述的扩展IReadOnlyCollection<T>抽象.请注意List<T>,例如,实现两者ICollection<T>IReadOnlyCollection<T>.

然而,它并没有这样设计.

我在这里错过了什么?为什么要选择当前的实现呢?


UPDATE

我正在寻找一个使用面向对象设计推理来解释原因的答案:

  • 一个具体的类,如List<T>实现IReadOnlyCollection<T> ICollection<T>

是一个比以下更好的设计:

  • ICollection<T>IReadOnlyCollection<T>直接实施

另请注意,这基本上与以下问题相同:

  1. 为什么不IList<T>实施IReadOnlyList<T>
  2. 为什么不IDictionary<T>实施IReadOnlyDictionary<T>

c# oop design-patterns c#-5.0 .net-4.5

52
推荐指数
2
解决办法
8021
查看次数

IEnumerable <T> vs. Array

我想要得到的想法,这将是发布对象的只读目录作为一个公共方法的最佳方式?从Eric Lippert的博客来看,阵列有点糟糕,因为有人可以轻松添加新条目.因此,每次调用该方法时都必须传递一个新数组.他建议,要通过IEnumerable<T>,因为这是每个定义只读(没有添加,删除方法),我练习了很长一段时间.但是在我们的新项目中,人们甚至开始创建这些的数组IEnumerables,因为他们不知道后面的DataSource,所以他们得到:处理警告可能多次枚举IEnumerable

我对技术方法感兴趣,如何解决这个难题.到目前为止,我提出的唯一解决方案是使用a IReadOnlyCollection,但这比使用更明确IEnumerable.

发布此类列表的最佳做法是什么,这些列表不应更改,但应声明为内存列表?

c# linq arrays data-structures

24
推荐指数
4
解决办法
2960
查看次数

甚至"IsNullOrEmpty"检查也会给出"可能多次枚举IEnumerable"的警告

关于"可能存在多个枚举"的SO有一个问题,但这个问题更具体.

请考虑以下方法,该方法接受IEnumerable<string>输入并对其每个元素执行给定方法:

public static bool SomeMethod(IEnumerable<string> enumerable)
{
    if (enumerable.IsNullOrEmpty())
    {
        // throw exception.
    }
    else
    {
        return (enumerable.All(SomeBooleanMethod));
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,IsNullOrEmpty只是一个运行的扩展方法

return (!ReferenceEquals(enumerable, null) || enumerable.Any());
Run Code Online (Sandbox Code Playgroud)

问题是ReSharper警告我"IEnumerable的可能的多个枚举",我真的不知道这是否真的是一个问题.

我理解警告的含义,但是如果你真的需要在无效或空洞的情况下检查并抛出异常,你在这种情况下真的可以做些什么?

c# resharper ienumerable

20
推荐指数
2
解决办法
8332
查看次数

14
推荐指数
2
解决办法
9696
查看次数

使用IReadOnlyCollection <T>而不是IEnumerable <T>来获取参数以避免可能的多次枚举

我的问题与这个关于使用IEnumerable<T>vs的问题有关IReadOnlyCollection<T>.

我也经常习惯IEnumerable<T>将集合作为返回类型和参数公开,因为它既可以是不可变的,也可以是懒惰的.

但是,我越来越关注代码中地点的扩散,我必须枚举一个参数以避免ReSharper给出的可能的多个枚举警告.我理解为什么ReSharper建议这一点,我同意它建议的代码(下面)以确保封装(即,没有关于调用者的假设).

 Foo[] arr = col as Foo[] ?? col.ToArray();
Run Code Online (Sandbox Code Playgroud)

但是,我发现此代码的重复性是污染性的,我同意一些IReadOnlyCollection<T>更好的替代方案,特别是本文中提出的观点,其中指出:

最近,我一直在考虑回归的优点和缺点 IEnumerable<T>.

从积极的一面,它大约是最小的一个接口获得,所以给人们留下你的方法作者比承诺更重的替代需要更多的灵活性IList<T>或(但愿)阵列.

但是,正如我在一篇文章中所概述的那样,IEnumerable<T>回归诱使来电者违反Liskov替代原则.这太容易让他们使用LINQ扩展方法,如Last()Count(),其语义IEnumerable<T>不答应.

我们需要的是一种更好的方法来锁定一个返回的集合,而不会让这种诱惑如此突出.(我想起Barney Fife艰难地学习这一课.)

IReadOnlyCollection<T>在.NET 4.5中输入new.它只添加一个属性IEnumerable<T>:Count属性.通过承诺计数,你向你的来电者保证你IEnumerable<T>确实有一个终点.然后,他们可以使用LINQ扩展方法,如Last()清醒的良心.

但是,正如观察者可能已经注意到的那样,本文仅讨论使用IReadOnlyCollection<T>返回类型.我的问题是,相同的论点同样适用于将其用于参数吗?对此的任何理论思考或评论也将受到赞赏.

事实上,我认为使用的一般经验法则IReadOnlyCollection<T>是,如果使用的话,可能存在多次枚举(相对于ReSharper警告)IEnumerable<T>.否则,请使用IEnumerable<T>.

c# resharper ienumerable readonly-collection .net-4.5

10
推荐指数
1
解决办法
1417
查看次数

IDictionary和IReadOnlyDictionary的扩展方法

我的问题类似于前一个问题,但这个问题的答案不适用于此问题.

好吧,我想为两者IDictionaryIReadOnlyDictionary接口编写扩展方法:

public static TValue? GetNullable<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key)
    where TValue : struct
{
    return dictionary.ContainsKey(key)
        ? (TValue?)dictionary[key]
        : null;
}

public static TValue? GetNullable<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
    where TValue : struct
{
    return dictionary.ContainsKey(key)
        ? (TValue?)dictionary[key]
        : null;
}
Run Code Online (Sandbox Code Playgroud)

但是当我将它用于实现两个接口的类(例如Dictionary<Tkey, TValue>)时,我得到了"模糊的调用".我不想打字var value = myDic.GetNullable<IReadOnlyDictionary<MyKeyType, MyValueType>>(key),我希望它只是var value = myDic.GetNullable(key).

这可能吗?

c# idictionary

7
推荐指数
2
解决办法
2204
查看次数

Any() 的多重枚举和使用

当我需要执行以下操作时,我试图找出 LINQ 的正确约定是什么

  • 如果有项目,则逐行打印它们
  • 如果没有项目,则打印"No items"

我想这样做的方式就像

if (items.Any())
{
    foreach (string item in items)
    {
        Console.WriteLine(item);
    }
}
else
{
    Console.WriteLine("No items");
}
Run Code Online (Sandbox Code Playgroud)

然而,这在技术上违反了多重枚举原则。一种不违反这一点的方法是

bool any = false;
foreach (string item in items)
{
    any = true;
    Console.WriteLine(item);
}   
if (!any)
{
    Console.WriteLine("No items");
}
Run Code Online (Sandbox Code Playgroud)

但显然,这不太优雅。

.net c# linq algorithm

7
推荐指数
1
解决办法
1006
查看次数

如何创建一个IEnumerable来在一个语句中懒惰地获取所有X.

C#不允许lambda函数表示迭代器块(例如,lambda函数内不允许"yield return").如果我想创建一个懒惰的枚举,例如在枚举时产生所有驱动器,我想做类似的事情

IEnumerable<DriveInfo> drives = {foreach (var drive in DriveInfo.GetDrives()) 
                                     yield return drive;};
Run Code Online (Sandbox Code Playgroud)

花了一段时间,但我认为这是获得该功能的一种方式:

var drives = Enumerable.Range(0, 1).SelectMany(_ => DriveInfo.GetDrives());
Run Code Online (Sandbox Code Playgroud)

有更惯用的方式吗?

c# lambda iterator lazy-evaluation

6
推荐指数
1
解决办法
391
查看次数

可能重复枚举IEnumerable

我写了以下代码:

IEnumerable<string> blackListCountriesCodes = 
pair.Criterion.CountriesExceptions.Select(countryItem => countryItem.CountryCode);

IEnumerable<string> whiteListCountriesCodes = 
pair.Criterion.Countries.Select(countryItem => countryItem.CountryCode);

return (!blackListCountriesCodes.Contains(Consts.ALL.ToString()) &&
        !blackListCountriesCodes.Contains(country) &&
        (whiteListCountriesCodes.Contains(Consts.ALL.ToString()) ||
        whiteListCountriesCodes.Contains(country)));
Run Code Online (Sandbox Code Playgroud)

resharper给我一个警告: Possible duplicate enumeration of IEnumerable

这是什么意思?为什么这是一个警告?

c# linq resharper

5
推荐指数
1
解决办法
301
查看次数