简体   繁体   English

字典初始化问题

[英]Dictionary initialization issue

Why does it work 为什么有效

Dictionary<string, Func<double, Func<double, double>>> functions = new Dictionary<string, Func<double, Func<double, double>>>
        {
            {"+", a => b => a + b },
            {"-", a => b => a - b },
            {"*", a => b => a * b },
            {"/", a => b => a / b },
            {"^", a => b => Math.Pow(a, b) }
        };
functions.Add("Square", a => b => functions["^"](a)(2));
functions.Add("Sqrt", a => b => functions["^"](a)(0.5));

and this doesn't 而且这不

Dictionary<string, Func<double, Func<double, double>>> functions = new Dictionary<string, Func<double, Func<double, double>>>()
        {
            {"+", a => b => a + b },
            {"-", a => b => a - b },
            {"*", a => b => a * b },
            {"/", a => b => a / b },
            {"^", a => b => Math.Pow(a, b) },
            {"Square", a => b => functions["^"](a)(2) },
            {"Sqrt", a => b => functions["^"](a)(0.5) }
        };

I am getting confused because if i declare "functions" like class field the second way would work. 我很困惑,因为如果我像类字段那样声明“函数”,第二种方法将起作用。

The issue is, that by the time of defining the member of the Dictionary: 问题是,在定义字典成员时:

{"Square", a => b => functions["^"](a)(2) },

the Dictionary object is not yet assigned to variable functions . Dictionary对象尚未分配给变量functions

But defining the last members as: 但是将最后一个成员定义为:

{"Square", a => b => Math.Pow(a, 2) },
{"Sqrt", a => b => Math.Pow(a, 0.5) }

Will definitely work. 一定会的。

You can do this instead: 您可以改为:

 Dictionary<string, Func<double, Func<double, double>>> functions  = null;

 functions = new Dictionary<string, Func<double, Func<double, double>>>()
    {
        {"+", a => b => a + b },
        {"-", a => b => a - b },
        {"*", a => b => a * b },
        {"/", a => b => a / b },
        {"^", a => b => Math.Pow(a, b) },
        {"Square", a => b => functions["^"](a)(2) },
        {"Sqrt", a => b => functions["^"](a)(0.5) }
    };

Your problem is that you cannot use a variable in its own declaration. 您的问题是您不能在其自己的声明中使用变量。 For example: 例如:

 int a = 2 * a;

Will also give you a compile error. 还会给你一个编译错误。

You can get around your issue by simply making sure the compiler knows that functions has a value before it's used. 您可以通过简单地确保编译器在使用functions之前就知道其值来解决问题。 It is safe to do this in your case, because your values are delegates, and will not be called until after the variable is declared. 在您的情况下,这样做是安全的,因为您的值是委托,并且直到声明变量后才被调用。

It works in a class declaration because when you declare a member in a class: 它在类声明中起作用,因为当您在类中声明成员时:

 public class Foo { public int a; }
 public static void Main() 
 {
      Console.WriteLine((new Foo()).a.ToString()); //"0"
      int a = 2 * a; //Compile error
 }

The compiler will automatically initialize a to be 0 when declared in a class. 在类中声明时,编译器会自动将a初始化为0。 However, in your own methods, the compiler does not act the same way. 但是,在您自己的方法中,编译器的行为方式不同。

Because functions is not assigned to anything at the point of initialization. 因为在初始化时functions未分配给任何东西。 For example this sample: 例如此示例:

var dict = new Dictionary<int, int> {
    { 1, 2 },
    { 3, dict[1] }       // CS0841  Cannot use local variable 'dict' before it is declared
};                       // CS0165  Use of unassigned local variable 'dict'

is the same as: 是相同的:

Dictionary<int, int> dict;               // dict is not assigned to anything and is null

var tempDictionary = new Dictionary<int, int>();
tempDictionary.Add(1, 2);
tempDictionary.Add(3, dict[1]);          // CS0165  Use of unassigned local variable 'dict'

dict = tempDictionary;                   // now dict is assigned and can be used

As a side note, square and sqrt functions that accept 2 parameters seems quite counterintuitive. 另外,接受2个参数的square和sqrt函数似乎很违反直觉。


Alternative could be using temporary variable, or declaring the power function before the dictionary. 另一种选择是使用临时变量,或在字典前声明幂函数。

// using FdFdd = System.Func<double, System.Func<double, double>>; // at the top of the file

FdFdd temp;
var functions = new Dictionary<string, FdFdd>()
{
    { "+", a => b => a + b },
    { "-", a => b => a - b },
    { "*", a => b => a * b },
    { "/", a => b => a / b },
    { "^", temp = a => b => Math.Pow(a, b) },
    { "Square", a => b => temp(a)(2) },
    { "Sqrt", a => b => temp(a)(0.5) }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM