我想实现一个字典,它只在访问元素时(而不是事先)动态创建自己的元素。为此,我想使用getter方法,但我根本找不到任何关于如何在dictionary元素的上下文中声明getter的信息。
我确实理解如何将getter添加到整个字典中(调用时必须返回字典),但我想实现的是在访问字典中的单个元素时调用的getter,这样我就可以动态创建该元素。该getter必须接收用于请求的密钥作为参数,并且必须返回相应的值。
我在文档中找不到该任务的任何语法。
您只需要在Dictionary<,>
上重新实现索引器
public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get
{
TValue value;
if (!TryGetValue(key, out value))
{
value = Activator.CreateInstance<TValue>();
Add(key, value);
}
return value;
}
set { base[key] = value; }
}
}
如果你需要一个更复杂的价值实例化,你可以使用激活器函数
public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
readonly Func<TKey, TValue> _activator;
public MyDictionary(Func<TKey, TValue> activator)
{
_activator = activator;
}
public new TValue this[TKey key]
{
get
{
TValue value;
if (!TryGetValue(key, out value))
{
value = _activator(key);
Add(key, value);
}
return value;
}
set { base[key] = value; }
}
}
用法:
static void Main(string[] args)
{
var dict = new MyDictionary<int, string>(x => string.Format("Automatically created Value for key {0}", x));
dict[1] = "Value for key 1";
for (int i = 0; i < 3; i++)
{
Console.WriteLine(dict[i]);
}
Console.Read();
}
虽然Kev的答案完全正确,而且是专业水平的,但它仍然给了我一段艰难的时间(并启动了许多富有成效的学习-谢谢Kev!)。正如你所知,我是一个学习C#的人,还有很多概念我还需要吸收。我想在这里为我自己的问题添加一个答案,以防其他人也有同样的问题,并且与我的理解水平相似。也许这会节省一些直播时间。
Kev在他的回答中使用了泛型——这是一个用C#引入的伟大概念。为了简化答案,我想在没有泛型的情况下展示它,并添加了很多注释,这些注释暗示了我必须查找的所有概念(部分不容易找到):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DictionaryElementsGetter_Test {
// class inherits from Dictionary<int, string>
public class MyDictionary : Dictionary<int, string> {
// new: hide element of base class to redefine it in derived class.
// see http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
// string this[int key]: create an indexer
// (actually: replace the indexer of base class, because of "new")
// see http://msdn.microsoft.com/en-us/library/2549tw02.aspx
new public string this[int key] {
get {
string value;
// out: pass argument by reference instead of by value
// This is the standard definition of TryGetValue.
// Beside the bool result that indicates the existence of the key-value-pair,
// TryGetValue also returns the value itself into this reference parameter (if key is found).
// see http://msdn.microsoft.com/en-us/library/ee332485.aspx
if( !TryGetValue( key, out value ) ) {
value = "abc" + key + "def";
Add( key, value );
// just to see when the getter really did an Add():
Console.Write( "ADDED!... " );
}
return value;
}
// base: access element of the base class Dictionary<int, string>
// see http://msdn.microsoft.com/en-us/library/hfw7t1ce(v=vs.100).aspx
set { base[key] = value; }
}
}
class Program {
static void Main( string[] args ) {
var dict = new MyDictionary();
dict[1] = "EXTERNAL VALUE";
for( int i = 0; i < 3; i++ ) {
Console.WriteLine( i + ": " + dict[i] );
}
/*
Output:
ADDED!... 0: abc0def
1: EXTERNAL VALUE
ADDED!... 2: abc2def
*/
for( int i = 0; i < 3; i++ ) {
Console.WriteLine( i + ": " + dict[i] );
}
/*
Output:
0: abc0def
1: EXTERNAL VALUE
2: abc2def
*/
Console.ReadKey();
}
}
}
它已经在框架中实现了。如果你打电话给
Dictionary<int, string> _myDictionary = new Dictionary<int, string>();
_myDictionary[1] = "Hello";
_myDictionary[2] = "World!";
您将使您的字典填充有键值对<1、"你好">,<2,"世界!">