2012-03-24 103 views
1

我试图根据下面的代码在排序前获取枚举中的单个值。该值显示两次。为什么Enumerable可重复在这里?

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

干杯,
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? 
... 

EDIT

Currency.GetCurrencies()被拨打电话到一个线程安全高速缓存的实施方案,其封装了一个字典并返回其值:

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

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

+0

'货币'是否执行'Equals'? – CodesInChaos 2012-03-24 15:34:14

+0

@CodeInChaos。它确实... – Berryl 2012-03-24 15:35:14

+2

然后,你可以拍一个'Distinct()'调用。 – CodesInChaos 2012-03-24 15:35:58

回答

1

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

我把一个小程序放在一起,我只得到'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)); 
    }  
} 
+0

尼古拉对多线程调用的分析似乎在这一点上是最有可能的。请参阅编辑的文章干杯 – Berryl 2012-03-24 16:51:59