【问题标题】:Constructor with optional parameters and the new()-constraint? [duplicate]带有可选参数和 new() 约束的构造函数? [复制]
【发布时间】:2014-01-14 02:20:39
【问题描述】:

我喜欢 C# 中的可选参数。但是当在构造函数中使用它们时,签名看起来(或可以看起来)像默认构造函数,使用泛型和new()-constraint 时事情会变得很奇怪:

class A<T> where T : new() { }

class B : A<B>
{        
    public B(bool b = false) { } 

    // 'B' must be a non-abstract type with a public **parameterless** constructor
    // in order to use it as parameter 'T' in the generic type or metho A<T>
}

在上面的示例中,编译器抱怨说没有无参数构造函数,迫使我添加类似:public B() : this(false) { }(实际上使可选版本变得多余)。

真的吗?我可以new B(),那有什么问题吗? (不是在编译过程中“扩展”了可选参数的方法吗?)我错过了一点吗?我知道提出这样的问题可能会导致诸如“这是一个设计决定”或“它更容易实现”之类的答案,但在大多数情况下,我只是忽略了一些东西。 :-)

【问题讨论】:

  • 不确定你的问题是什么:显然带有可选参数的构造函数是 not 没有参数的构造函数。那么您是在问为什么做出这个决定(不太可能得到扩展答案),如何解决它(但您已经发布了代码示例)或完全不同的东西?
  • 那么,是什么让像上面显示的构造函数与没有参数的构造函数不同,只要它可以在没有参数的情况下调用?也许我缺乏对可选参数如何编译/解释的理解。我的问题实际上是:这种区分是否有更深层次的含义? (当然,如果没有,这个问题在某种程度上毫无意义。)
  • @MarcinJuraszek 建议的答案包含非常详细的解释。简短 - public B(bool b = false) 不会在任何时候(编译/运行时)自动创建 public B() - 所以类不包含无参数构造函数。
  • 哈!感谢您的链接 - 这几乎是答案:问题是,可选参数是编译器功能,因此被转换为 CLR 的具有参数和属性(具有默认值)的方法。由于通用约束是 CLR 的主题,因此无法针对这种情况自动评估它们。 (至少只要 CLR 将来不支持可选参数,那么可能也会支持这种构造。)

标签: c# generics constructor compiler-errors optional-parameters


【解决方案1】:

我不是 100% 确定您所说的 在编译期间是否“扩展”了带有可选参数的方法? 但我会说不。

不是在编译期间创建另一个没有可选参数的方法,而是将每个没有指定该参数的方法调用更改为包含默认值。

所以每个

var b = new B();

在编译期间改为

var b = new B(false);

并且为您创建了非额外的构造函数。没有这样的:

public B() : this(false) {}

在编译期间添加到您的代码中。

我认为,当new() 约束设置它时,不可能将带有可选参数的构造函数的类型用作泛型类型。

【讨论】:

  • 是的,我同意,谢谢。但是像这样的争论不能所有的通用调用都被替换吗? new T() -> new T(false)。但是,关于反对它的其他论点,我不想采取这个立场:-)。
  • 但问题是,泛型是 CLR 特性,它必须与不支持可选参数的语言一起使用。
  • 是的,我也意识到了这一点。所以结论是这样的:它不起作用,并且有充分的理由。解决方法:在这种情况下不要使用可选参数,或者至少指定一个额外的无参数构造函数。 (好吧,这很简单......)
【解决方案2】:

考虑这个定义:

class B
{
    private readonly bool _z;
    public bool Z { get { return _z; } }

    private readonly int _k;
    public int K { get { return _k; } }


    public B(bool z = false)
    {
        _z = z;
    }
    public B(int k = 1)
    {
        _k = k;
    }
}

编译器不知道在你的泛型类中使用哪个构造函数。当然有办法解决这个问题。其中之一是要求该类应具有无参数构造函数,以便完全符合您的描述。

【讨论】:

  • 有趣的一点,谢谢!我没想到。因此,除了上述 Marcin Juraszek 链接中的方面 postet 之外,还有很多原因可以说明这是一个有问题的案例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2015-04-08
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多