为什么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值只显示一次,这是一个可接受的解决方案。不确定为什么它在不强制枚举的情况下出现两次,尽管线程似乎在根目录下。。
就像@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));
}
}