为什么Enumerable Concat在这里重复

本文关键字:在这里 Concat Enumerable 为什么 | 更新日期: 2023-09-27 18:28:49

根据下面的代码,在对枚举进行排序之前,我试图在枚举中获取一个值。该值显示两次。

为什么?最好的解决方案是什么?

干杯,
Berryl

    private static IEnumerable<Currency> _commonCurrencies;
    public static IEnumerable<Currency> GetCommonCurrencies() {
        return _commonCurrencies ??
               (_commonCurrencies
                = Currency.GetCachedCurrencies()
                      .Concat(new[] {Currency.Get(CurrencyIsoCode.KWD)})
                      .Where(x => !x.AlphabeticCode.StartsWith("X", StringComparison.InvariantCultureIgnoreCase))
                      .OrderBy(x => x.AlphabeticCode));
    }

输出

...
JPY
KWD
KWD  // repeats?
...

编辑

Currency.GetCurrencies()正在调用线程安全缓存的实现,该缓存封装Dictionary并返回其值:

public ICollection<TValue> Values { get { return _inner.Values; } }

我没有这种类型的。将代码更改为"slap"ToArray()可以修复问题,因此concat值只显示一次,这是一个可接受的解决方案。不确定为什么它在不强制枚举的情况下出现两次,尽管线程似乎在根目录下。。

为什么Enumerable Concat在这里重复

就像@CodeInChaos所说的,如果GetCachedCurrents不包含元素,可能是因为Lazy Evaluation。

我编写了一个小程序,只得到了一个"KWD"实例。

enum CurrencyIsoCode
{
    USD,
    KWD,
    JPY,
    XCD,
    TVD
}
class Currency
{
    public Currency() : this(false) { }
    public Currency(bool inner) { }
    public static IEnumerable<Currency> GetCachedCurrencies()
    {
        return new[] { 
             new Currency () { currencyCode = CurrencyIsoCode.USD },
             new Currency () { currencyCode = CurrencyIsoCode.JPY },
             new Currency () { currencyCode = CurrencyIsoCode.XCD }
           };
    }
    public  CurrencyIsoCode  currencyCode { set; get; }
    public string AlphabeticCode
    {
        get { return currencyCode.ToString(); } 
    }
    public static Currency Get(CurrencyIsoCode isOCode)
    {
        return new Currency() { currencyCode = isOCode };
    }
}
class Program
{
    private static IEnumerable<Currency> _commonCurrencies = null;
    static void Main(string[] args)
    {
        var currencies = GetCommonCurrencies();
        foreach (var curr in currencies)
            Console.WriteLine(curr.AlphabeticCode);
        Console.Read();
    }

    public static IEnumerable<Currency> GetCommonCurrencies() 
    {
        return _commonCurrencies ??
           ( _commonCurrencies
            = Currency.GetCachedCurrencies()
                  .Concat(new[] {Currency.Get(CurrencyIsoCode.KWD)})
                  .Where(x => !x.AlphabeticCode.StartsWith("X", StringComparison.InvariantCultureIgnoreCase))
                  .OrderBy(x => x.AlphabeticCode));
    }       
}