【问题标题】:C# Optional Array Parameter for Class类的 C# 可选数组参数
【发布时间】:2017-02-19 15:20:40
【问题描述】:

我知道这可以使用 null 来完成,所以我有一个解决方法,但我想知道是否有更好的方法可以为类设置可选的 int[] 参数?

class PriceLevels
{
    public int[] priceLevels { get; }
    private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels(int[] newPriceLevels = defaultPriceLevels)
    {
        priceLevels = newPriceLevels;
    }
}

这给了我一个错误,说这是一个无效的表达式 defaultPriceLevels 必须是常量。我该如何解决这个问题?

我能想到的一种解决方法是这样,但我不太喜欢这个解决方案

class PriceLevels
{
    public int[] priceLevels { get; }
    private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels(int[] newPriceLevels = null)
    {
        if(newPriceLevels == null) 
            priceLevels = defaultPriceLevels;
        else 
            priceLevels = newPriceLevels;
    }
}

【问题讨论】:

标签: c# class optional-parameters


【解决方案1】:

更好的设计是让 2 个构造函数 (constructor overload) 一个得到int[] 而另一个没有:

class PriceLevels
{
    public int[] priceLevels { get; set; }
    private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels()
    {
        priceLevels = defaultPriceLevels;
    }

    public PriceLevels(int[] newPriceLevels)
    {
       priceLevels = newPriceLevels;
    }
}

如果不是,不知道我是否会称其为“更好”,但您可以使用params keyword

class PriceLevels
{
    public int[] priceLevels { get; set; }
    private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels(params int[] newPriceLevels)
    {
        priceLevels = newPriceLevels.Length == 0 ? defaultPriceLevels : newPriceLevels;
    }
}

此外,根据设计,我不相信 PriceLevels 有责任决定默认值是什么,并且在任何情况下它都应该将其作为依赖项 - 请参阅 SOLID@ 987654324@。那么你将只有 1 个构造函数:

class PriceLevels
{
    public int[] priceLevels { get; set; }

    public PriceLevels(int[] newPriceLevels)
    {
       priceLevels = newPriceLevels;
    }
}

【讨论】:

  • priceLevels 属性也应该有设置器。
  • null-coalescing 操作符本身使它“更好”!
  • 谢谢,我想我可能会接受您的最终建议并重新考虑我的结构。另外,对这个 setter 感到好奇......如果我所做的只是在类初始化时设置该值,为什么我有必要拥有一个 setter(即使它是私有的)?
  • @Adjit - Cubicle.Jockey 在下方评论二传手。
  • @Gilad,我不认为 params 的第一部分有效 - 如果你调用它不带参数,你仍然会收到 空数组,而不是 @987654333 @.
【解决方案2】:

你可以重载你的构造函数。

class PriceLevels
{
    public int[] priceLevels { get; private set; }
    private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels()
    {
        priceLevels = defaultPriceLevels;
    }

    public PriceLevels(int[] newPriceLevels)
    {
       priceLevels = newPriceLevels;
    }
}

【讨论】:

  • priceLevels 属性也应该有设置器。
  • 添加了一个私人二传手。谢谢。
  • 如果 C# 6.0 仅在构造函数中设置值,则不需要私有集。
【解决方案3】:

您可以创建另一个不带参数的构造函数,将您的 defaultPriceLevels 变量传递给您已有的构造函数吗?您也必须将变量更改为静态。

例如

class PriceLevels
{
    public int[] priceLevels { get; }
    private static int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

    public PriceLevels(int[] newPriceLevels = null)
    {
        if (newPriceLevels == null) priceLevels = defaultPriceLevels;
        else priceLevels = newPriceLevels;
    }

    public PriceLevels() : this(defaultPriceLevels)
    { }
}

【讨论】:

  • @DongWei 你一定能做到。在 linqpad 中尝试一下。
  • :对不起,我应该把我说的话贴给OP而不是你:)
  • 喜欢这个解决方案,但您不应该在其中一个构造函数中将 newPriceLevels 设为可选,在我看来这没有任何好处 +1
【解决方案4】:

Crowd 中的另一个选项 :),它最接近您的原始代码

class PriceLevels
{
  public int[] priceLevels { get; set; }

  private readonly int[] defaultPriceLevels = { 2, 3, 3, 4, 5, 6 };

  public PriceLevels(int[] newPriceLevels = null)
  {
     priceLevels = newPriceLevels ?? defaultPriceLevels;
  }
}

【讨论】:

    【解决方案5】:

    只需创建构造函数的重载!一行代码就可以轻松搞定!

    public PriceLevels() : this(defaultPriceLevels) { }
    

    然后,从原始构造函数中移除默认参数值:

    public PriceLevels(int[] newPriceLevels)
    

    其实你还需要将defaultPriceLevels声明为static。希望你不介意。

    【讨论】:

      【解决方案6】:

      可选的数组参数在 C# 中是不可能的。来自MSDN

      每个可选参数都有一个默认值作为其定义的一部分。 如果没有为该参数发送任何参数,则使用默认值。 默认值必须是以下表达式类型之一:

      • 一个常量表达式;
      • new ValType() 形式的表达式,其中 ValType 是值类型,例如枚举或结构;
      • 一个表达式 表单 default(ValType),其中 ValType 是值类型。

      因此必须使用“解决方法”。要么检查 null (如你所建议的那样),要么你可以使用默认构造函数。

      【讨论】:

        猜你喜欢
        • 2012-01-03
        • 2011-03-25
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2013-01-08
        相关资源
        最近更新 更多