gpt4 book ai didi

c# - 如何从 IDictionary 中获取 IEnumerable

转载 作者:行者123 更新时间:2023-11-30 14:37:04 27 4
gpt4 key购买 nike

我基本上想这样做:

if(obj is IDictionary)
{
return "{" + string.Join(Environment.NewLine, ((IDictionary)obj).Cast<DictionaryEntry>().Select(e => string.Format(" {0}: {1}", PrettyString(e.Key), PrettyString(e.Value)))) + "}";
}

但我一直收到无效的强制转换。我能做到

foreach(DictionaryEntry e in (IDictionary)obj)

那为什么我不能这样做呢?


我觉得这很好奇。我写了一个扩展来解决这个问题:

static class EnumerableExt
{
public static IEnumerable<DictionaryEntry> Entries(this IDictionary dict)
{
foreach (var item in dict) yield return (DictionaryEntry)item;
}
}

那么我可以这样做:

((IDictionary)obj).Entries().Select(...)

奇怪的是 Resharper 告诉我可以用这个替换我的扩展:

return dict.Cast<DictionaryEntry>();

但这会引发异常。这是 Resharper 中的错误吗?或者 Cast 是如何工作的?我想 Cast 会像我的扩展一样工作。

编辑:啊..我读了this answer更紧密一点。还是很奇怪。

最佳答案

键和值类型在编译时是否已知?如果是这样,您可以为 pretty-print 制作一个通用方法,让编译器为您推断类型,例如:

static void Main(string[] args)
{
var obj = new Dictionary<string, string>()
{
{ "foo", "bar" },
{ "baz", "ack" },
};

var stringVersion = GetStringVersion(obj);

Console.WriteLine(stringVersion);
}

private static string GetStringVersion<TKey, TValue>(Dictionary<TKey, TValue> dict)
{
return "{" + string.Join(Environment.NewLine, dict.Select(e => string.Format(" {0}: {1}", e.Key, e.Value))) + "}";
}

就您所看到的行为而言,由于向后兼容和设计决策,这是一个已知的奇怪案例:

http://blogs.msdn.com/b/bclteam/archive/2004/09/03/225473.aspx

We discussed a problem with implementation of IEnumerable on Dictionary. What type should IEnumerable.GetEnumerator().Current return? KeyValuePair or DictionaryEntry? Same for ICollection.CopyTo. Instances of what type should be copied to the array?

We decided the following:

  1. IEnumerable and ICollection interface implementations will use KeyValuePair<K,V> as the item type.
  2. IDictionary specific members (GetEnumerator returning IDictionaryEnumerator) will use DictionaryEntry as the item type.

The reason is that we are in a process of making a change where IEnumerator<T> would extend IEnumerator. It would be very strange if walking the hierarchy from Dictionary<K,V>->IEnumerable<T>->IEnumerable we suddenly changed the type of the item returned from enumerators.

由于该设计决策(在创建 .NET 2.0 期间),当您对非泛型 IEnumerable 进行操作时,GetEnumerator() 调用返回 IDictionaryEnumerator,并且结果项的类型为 DictionaryEntry(大概是为了向后兼容具有哈希表类型的迭代)。但是,一旦调用通用 IEnumerable(执行 Cast() 或 OfType() 后会发生这种情况),您将获得 KeyValuePair 项目。

请注意,这是在非通用上下文中使用 Dictionary 的一个特别奇怪的地方 - Hashtable(仍然)作为 DictionaryEntry 项很好地迭代,并且对 Dictionary 的“正常”迭代为您提供 KeyValuePair 项。

正如其他人所说,如果可以的话,您应该坚持使用通用访问,因为它可以让您避免在 Dictionary 的设计决策中出现这个小问题。

关于c# - 如何从 IDictionary 中获取 IEnumerable<DictionaryEntry>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9713311/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com