Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#4.0中字典元素的getter_C#_Dictionary_Getter - Fatal编程技术网

C#4.0中字典元素的getter

C#4.0中字典元素的getter,c#,dictionary,getter,C#,Dictionary,Getter,我想实现一个字典,它只在被访问时(而不是事先)动态创建自己的元素。为此,我想使用一个getter方法,但我没有找到任何关于如何在dictionary元素上下文中声明getter的信息 我确实理解如何向整个字典添加getter(调用时必须返回字典),但我想做的是实现一个getter,当访问字典中的单个元素时调用它,这样我就可以动态创建该元素。该getter必须接收用于请求的键作为参数,并且必须返回相应的值 我在文档中找不到该任务的任何语法。它已经在框架中实现了。如果你打电话 Dictionary&

我想实现一个字典,它只在被访问时(而不是事先)动态创建自己的元素。为此,我想使用一个getter方法,但我没有找到任何关于如何在dictionary元素上下文中声明getter的信息

我确实理解如何向整个字典添加getter(调用时必须返回字典),但我想做的是实现一个getter,当访问字典中的单个元素时调用它,这样我就可以动态创建该元素。该getter必须接收用于请求的键作为参数,并且必须返回相应的值


我在文档中找不到该任务的任何语法。

它已经在框架中实现了。如果你打电话

Dictionary<int, string> _myDictionary = new Dictionary<int, string>();

_myDictionary[1] = "Hello";
_myDictionary[2] = "World!";
Dictionary\u myDictionary=newdictionary();
_myDictionary[1]=“你好”;
_myDictionary[2]=“世界!”;

您将使用键值对填充词典,

您只需在
词典

公共类MyDictionary:Dictionary
{
公共新TValue此[TKey]
{
得到
{
t价值;
如果(!TryGetValue(键,输出值))
{
value=Activator.CreateInstance();
添加(键、值);
}
返回值;
}
set{base[key]=value;}
} 
}
如果需要更复杂的值实例化,可以使用activator函数

 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; }
    } 
}
公共类MyDictionary:Dictionary
{
只读函数激活器;
公共MyDictionary(Func激活器)
{
_激活剂=激活剂;
}
公共新TValue此[TKey]
{
得到
{
t价值;
如果(!TryGetValue(键,输出值))
{
值=_激活器(键);
添加(键、值);
}
返回值;
}
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();
}
static void Main(字符串[]args)
{
var dict=newmydictionary(x=>string.Format(“为键{0}自动创建的值”,x));
dict[1]=“键1的值”;
对于(int i=0;i<3;i++)
{
控制台写入线(dict[i]);
}
Console.Read();
}

虽然Kev的答案是完全正确的,而且是在专业水平上给出的,但它仍然给了我一段艰难的时间(并且引发了许多富有成效的学习——谢谢Kev!)。正如你所说,我是C#的学习者,还有很多概念我还需要吸收。我想在这里为我自己的问题添加一个答案,以防其他人也有同样的问题,并且与我的理解水平相似。也许这会节省一些现场时间

Kev在回答中使用了泛型——这是C#2引入的一个伟大概念。为了简化答案,我想在没有泛型的情况下展示它,并添加了大量注释,这些注释为我必须查找的所有概念提供了提示(部分不容易找到):

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间字典YelementGetter_测试{
//类继承自字典
公共类MyDictionary:Dictionary{
//新建:隐藏基类的元素以在派生类中重新定义它。
//看http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
//字符串[int key]:创建索引器
//(实际上:替换基类的索引器,因为“new”)
//看http://msdn.microsoft.com/en-us/library/2549tw02.aspx
新建公共字符串this[int key]{
得到{
字符串值;
//out:通过引用而不是通过值传递参数
//这是TryGetValue的标准定义。
//除了表示存在键值对的bool结果之外,
//TryGetValue还将值本身返回到此引用参数中(如果找到键)。
//看http://msdn.microsoft.com/en-us/library/ee332485.aspx
如果(!TryGetValue(键,输出值)){
value=“abc”+键+定义;
添加(键、值);
//只是想看看getter何时真正执行了Add():
控制台。写入(“添加!”);
}
返回值;
}
//base:基类字典的access元素
//看http://msdn.microsoft.com/en-us/library/hfw7t1ce(v=vs.100).aspx
set{base[key]=value;}
}
}
班级计划{
静态void Main(字符串[]参数){
var dict=new MyDictionary();
dict[1]=“外部值”;
对于(int i=0;i<3;i++){
Console.WriteLine(i+“:”+dict[i]);
}
/* 
输出:
已添加!…0:abc0def
1:外部价值
添加!…2:abc2def
*/
对于(int i=0;i<3;i++){
Console.WriteLine(i+“:”+dict[i]);
}
/* 
输出:
0:abc0def
1:外部价值
2:abc2def
*/
Console.ReadKey();
}
}
}

这是什么?看看这不是字典,这是缓存工厂。我将使用
GetValue(key)
方法和私有字典字段实现一个自定义类;OP询问的是Getter。对不起,Andrew,这不是我要找的。@Jpsy您能澄清一下吗?你的意思是
string aValue=\u myDictionary[1]
?如果是这样,那么您需要小心,因为任何不可变的类型或值类型在返回whow后都无法更新。好东西!非常感谢你为我指明了这个方向。Kev,我正在努力使用你的两个类。你能编辑一下你的答案,并给他们两个简短的用法示例吗?那将大有帮助。谢谢@你到底有什么问题?这应该很简单。请看我添加的使用示例,我正在摆弄第一个c
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();
}
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();

    }
  }
}