为什么Enumerable Concat在这里重复?

时间:2012-03-24 15:32:13

标签: c# .net linq

我正在尝试在订购之前在枚举中获取单个值,如下面的代码所示。该值显示两次。

为什么呢?什么是最好的解决办法?

干杯,
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()正在调用Thread Safe缓存的实现,该缓存包装Dictionary并返回其值:

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

我没有这种类型。将代码更改为'slap'ToArray()可以解决问题,以便concat值只显示一次并且是可接受的解决方案。不知道为什么它会在没有强制枚举的情况下出现两次,尽管线程似乎是根源..

1 个答案:

答案 0 :(得分:1)

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

我整理了一个小程序,我只得到1个'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));
    }       
}