实例化:将列表移动到参数中

时间:2015-11-10 22:38:21

标签: c# constructor instantiation

我是C#的新手,并且一直在努力寻找一种在构造函数中初始化列表的惯用方法。

相关问题并不能解决问题:

这有效,但有一个缺陷:

class Datapoint
{
    public bool Debug { get; set; }
    public string Pattern { get; private set; }

    // I would prefer to initialize this list in the constructor
    public List<Dictionary<string, dynamic>> operations = 
            new List<Dictionary<string, dynamic>>();

    // constructor
    public Datapoint(bool debug = false, 
                string pattern = ""
                // I would prefer operations to go here 
                // but the following doesn't work:
                // List<Dictionary<string, dynamic>> operations = 
                //     new List<Dictionary<string, dynamic>>()
                ) 
    {
        Debug = debug;
        Pattern = pattern;
    }
}


// Let's define some Datapoints
class Definitions 
{
    public static Datapoint turtles = new Datapoint
    (
        pattern: @"turtle pattern",
        // I would prefer operations to go here
    )
    {
        operations =
                { new Dictionary<string, dynamic>
                    {
                        ["func"] = "stitch_lines"
                    }
                }
    };
}

缺点是我无法将操作设置为私有,否则在创建海龟时会出错。

理想情况下,我希望operations成为构造函数的参数,但我遗漏了一些内容,因为我尝试的每个组合都会产生此错误:

  

操作的默认参数值必须是编译时   恒定。

提前感谢任何见解。

3 个答案:

答案 0 :(得分:2)

您可以接受null,然后在构造函数中检查它:

public Datapoint(
    bool debug = false, 
    string pattern = "",
    List<Dictionary<string, dynamic>> operations = null
)
{
    Debug = debug;
    Pattern = pattern;
    this.operations = operations ?? new List<Dictionary<string, dynamic>>();
}

但是,请参阅 D Stanley 的回答,以讨论一般情况下的缺点。

答案 1 :(得分:1)

如错误所示,默认值必须是编译时常量。我会这样做两个重载:

// constructor
public Datapoint(bool debug = false, 
            string pattern = "")
{
    Debug = debug;
    Pattern = pattern;

    operations = new List<Dictionary<string, dynamic>>();
}

public Datapoint(List<Dictionary<string, dynamic>> operations,
            bool debug = false, 
            string pattern = "")
{
    Debug = debug;
    Pattern = pattern;

    this.operations = operations;
}

请注意,您需要对第二个重载中的参数重新排序,因为可选参数必须位于参数列表的末尾。

答案 2 :(得分:1)

避免以这种方式使用可选参数

//constructor
public Datapoint(
    bool debug = false, //dangerous
    string pattern = "",//dangerous
    List<Dictionary<string, dynamic>> operations = null
)

改为使用:

//constructor
public Datapoint(
    bool? debug = null, 
    string pattern = null,
    List<Dictionary<string, dynamic>> operations = null
)
{
    Debug = debug.HasValue && debug.Value;
    Pattern = pattern;
    this.operations = (operations == null) ? 
              new List<Dictionary<string, dynamic>>() 
              : operations ;
}

来源: C# In Depth – Optional Parameters and Named Arguments