是否可以创建一个'自初始化'c# 6.0中的字典扩展方法
本文关键字:方法 扩展 字典 初始化 一个 是否 创建 | 更新日期: 2023-09-27 18:15:16
是否有可能在字典上创建一个扩展方法,如果字典为空,则能够自我初始化?
我在想下面的事情:
public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
// Initialize the Dictionary if null
dictionary = dictionary ?? new Dictionary<TKey, TValue>();
// Update or insert value
dictionary[key] = value;
}
实际应用示例:
// null Dictionary
Dictionary<string, string> dict = null;
// Self-initializing
dict.AddOrUpdate("Key", "Value");
或者作为属性:
// Self-initializing
class.nullDict.AddOrUpdate("Key", "Value");
不
要使其工作,您必须通过ref
传递参数,而这是不允许的。
当this关键字修改静态方法的第一个参数时,它向编译器发出信号,表明该方法是扩展方法。不需要也不允许在扩展方法的第一个参数上使用修饰符。
您所要求的内容在如何获得更改原始对象的扩展方法中进行了讨论?结果是:在引用类型的情况下,您所能做的就是操作对象。你不能赋值它,因为那样你将处理一个本地副本,而不是最初传递给方法的对象:
public static void Foo(this Object bar)
{
// assignment
bar = new ...();
// here you're NOT calling Baz() on the object passed into the method
bar.Baz();
}
注意那些是引用类型语义。你甚至不能对值类型做任何有意义的事情:
public static void PlusOne(this int number)
{
number++;
}
这将永远不会修改原始值,因为它们是根据定义按值传递的:这个扩展方法对调用它的值的副本进行操作。
话虽这么说,这更多的是关于期望的问题。有人在读这段代码吗?
Dictionary<string, string> dict = null;
dict.AddOrUpdate("Key", "Value");
将期望NullReferenceException
(如果AddOrUpdate()
是Dictionary<TKey, TValue>
的成员方法)或ArgumentNullException(在扩展方法的情况下),甚至编译器也会期望。
你认为你需要这个有一个潜在的原因。当然,实现"从扩展方法返回新的或更新的字典,并在每次修改时赋值"的答案是有效的,但会给您带来非常笨拙的语法:
Dictionary<string, string> dict = null;
dict = dict.AddOrUpdate("Key", "Value");
并且您只需要忘记不寻常的dict =
一次就可以在超出其使用范围的某个时刻获得NRE/ANE。如果你对函数式编程感兴趣,这可能没问题,但c#不是。
因此:确保在尝试添加键值对之前对字典进行初始化,这样所有这些不寻常的需求就消失了。它可能像这样简单:
Dictionary<string, string> dict = possiblyNullVariable ?? new Dictionary<string, string>();
我认为这对每个使用它的人来说都是非常困惑的,因为对空对象执行操作并不常见。
所以即使可能,我也宁愿使用
Dictionary<string, string> dict = new Dictionary<string, string>();
你可以,但是你必须将返回类型从void
更改为Dictionay
,这将是一个非常糟糕的设计。这样,每次使用扩展名时,调用者都必须执行赋值。
public static IDictionary<TKey, TValue> AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
// Initialize the Dictionary if null
if (dictionary == null)
dictionary = new Dictionary<TKey, TValue>();
// Update value if key already exists
if (dictionary.ContainsKey(key))
dictionary[key] = value;
else
// Insert value with the given key
dictionary.Add(key, value);
return dictionary;
}
我建议更改方法的签名:
// Let's return the dictionary (either passed or created)
public static IDictionary<TKey, TValue> AddOrUpdate<TKey, TValue>(
this IDictionary<TKey, TValue> dictionary,
TKey key,
TValue value) {
IDictionary<TKey, TValue> result = dictionary;
// Initialize the Dictionary if null
if (result == null)
result = new Dictionary<TKey, TValue>();
// Update value if key already exists
if (result.ContainsKey(key))
result[key] = value;
else
// Insert value with the given key
result.Add(key, value);
return result;
}
…
Dictionary<string, string> dict = null;
dict = dict.AddOrUpdate("Key", "Value");
我认为你需要的是一个自初始化属性:
private Dictionary<string, string> dict;
public Dictionary<string, string> Dict => this.dict ?? (this.dict = new Dictionary<string, string>());
那么,无论何时使用Dict
,它都保证被初始化