2012-03-24 8 views
1

Ich versuche, einen einzelnen Wert in einer Aufzählung zu erhalten, bevor Sie es bestellen, wie im folgenden Code beschrieben. Der Wert wird zweimal angezeigt.Warum wiederholt sich hier Enumerable Concat?

Warum? Was ist die beste Lösung?

Cheers,
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)); 
    } 

Ausgang

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

EDIT

Currency.GetCurrencies() macht einen Anruf zu einer Implementierung eines Thread-sicher-Cache, die ein Wörterbuch hüllt und gibt seine Werte zurück:

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

Ich besitze diesen Typ nicht. Wenn Sie den Code ändern, um ein ToArray() zu "schlagen", wird das Problem behoben, sodass der concat-Wert nur einmal angezeigt wird und eine akzeptable Lösung darstellt. Nicht sicher, warum es zweimal auftaucht, ohne die Aufzählung zu erzwingen, obwohl Threading scheint an der Wurzel zu sein.

+0

Hat 'Currency'' Equals' implementiert? – CodesInChaos

+0

@CodeInChaos. es tut ... – Berryl

+2

Dann können Sie auf einen 'Distinct()' Anruf schlagen. – CodesInChaos

Antwort

1

Wie @CodeInChaos sagte, ist es wahrscheinlich wegen Lazy Evaluation, wenn GetCachedCurrencies das Element nicht enthält.

Ich habe ein kleines Programm zusammengestellt und ich bekomme nur 1 Instanz von '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

Nikolas Analyse eines Multiple-Thread-Aufrufs erscheint zu diesem Zeitpunkt am wahrscheinlichsten. Siehe den bearbeiteten Post. Prost – Berryl

Verwandte Themen