was*_*atz 216 c# collections dictionary
我发现自己现在经常在我的代码中使用当前模式
var dictionary = new Dictionary<type, IList<othertype>>();
// Add stuff to dictionary
var somethingElse = dictionary.ContainsKey(key) ? dictionary[key] : new List<othertype>();
// Do work with the somethingelse variable
Run Code Online (Sandbox Code Playgroud)
或者有时候
var dictionary = new Dictionary<type, IList<othertype>>();
// Add stuff to dictionary
IList<othertype> somethingElse;
if(!dictionary.TryGetValue(key, out somethingElse) {
somethingElse = new List<othertype>();
}
Run Code Online (Sandbox Code Playgroud)
这两种方式都让人觉得很迂回.我真正想要的是这样的
dictionary.GetValueOrDefault(key)
Run Code Online (Sandbox Code Playgroud)
现在,我可以为字典类编写一个扩展方法来为我做这个,但我想我可能会遗漏已经存在的东西.那么,有没有办法以更简单的方式做到这一点,而无需在字典中编写扩展方法?
Jon*_*eet 280
TryGetValue 将已将类型的默认值分配给字典,因此您可以使用:
dictionary.TryGetValue(key, out value);
Run Code Online (Sandbox Code Playgroud)
并忽略返回值.然而,真正将刚刚返回default(TValue),而不是一些自定义的默认值(也没有,更有效,执行委托的结果).框架中没有任何更强大的功能.我建议两种扩展方法:
public static TValue GetValueOrDefault<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
TValue defaultValue)
{
TValue value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}
public static TValue GetValueOrDefault<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
Func<TValue> defaultValueProvider)
{
TValue value;
return dictionary.TryGetValue(key, out value) ? value
: defaultValueProvider();
}
Run Code Online (Sandbox Code Playgroud)
(你当然可能想要进行参数检查:)
rob*_*ity 28
我知道这是一个老帖子,我喜欢扩展方法,但这里是一个简单的类,我不时使用它来处理字典,当我需要默认值.
我希望这只是基类Dictionary类的一部分.
public class DictionaryWithDefault<TKey, TValue> : Dictionary<TKey, TValue>
{
TValue _default;
public TValue DefaultValue {
get { return _default; }
set { _default = value; }
}
public DictionaryWithDefault() : base() { }
public DictionaryWithDefault(TValue defaultValue) : base() {
_default = defaultValue;
}
public new TValue this[TKey key]
{
get {
TValue t;
return base.TryGetValue(key, out t) ? t : _default;
}
set { base[key] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
但要注意.通过子类化和使用new(因为override在本机Dictionary类型上不可用),如果一个DictionaryWithDefault对象被上传到普通Dictionary,则调用索引器将使用基本Dictionary实现(如果丢失则抛出异常)而不是子类的实现.
Joh*_*mez 23
我创建了一个DefaultableDictionary来完全按照你的要求去做!
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace DefaultableDictionary {
public class DefaultableDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
private readonly IDictionary<TKey, TValue> dictionary;
private readonly TValue defaultValue;
public DefaultableDictionary(IDictionary<TKey, TValue> dictionary, TValue defaultValue) {
this.dictionary = dictionary;
this.defaultValue = defaultValue;
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
return dictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public void Add(KeyValuePair<TKey, TValue> item) {
dictionary.Add(item);
}
public void Clear() {
dictionary.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item) {
return dictionary.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
dictionary.CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<TKey, TValue> item) {
return dictionary.Remove(item);
}
public int Count {
get { return dictionary.Count; }
}
public bool IsReadOnly {
get { return dictionary.IsReadOnly; }
}
public bool ContainsKey(TKey key) {
return dictionary.ContainsKey(key);
}
public void Add(TKey key, TValue value) {
dictionary.Add(key, value);
}
public bool Remove(TKey key) {
return dictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value) {
if (!dictionary.TryGetValue(key, out value)) {
value = defaultValue;
}
return true;
}
public TValue this[TKey key] {
get
{
try
{
return dictionary[key];
} catch (KeyNotFoundException) {
return defaultValue;
}
}
set { dictionary[key] = value; }
}
public ICollection<TKey> Keys {
get { return dictionary.Keys; }
}
public ICollection<TValue> Values {
get
{
var values = new List<TValue>(dictionary.Values) {
defaultValue
};
return values;
}
}
}
public static class DefaultableDictionaryExtensions {
public static IDictionary<TKey, TValue> WithDefaultValue<TValue, TKey>(this IDictionary<TKey, TValue> dictionary, TValue defaultValue ) {
return new DefaultableDictionary<TKey, TValue>(dictionary, defaultValue);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该项目是IDictionary对象的简单装饰器和扩展方法,使其易于使用.
DefaultableDictionary将允许在字典周围创建包装器,该字典在尝试访问不存在的键或通过IDictionary中的所有值枚举时提供默认值.
例: var dictionary = new Dictionary<string, int>().WithDefaultValue(5);
关于用法的博客文章.