带有可选参数和new() - 约束的构造函数?

时间:2014-01-14 02:20:39

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

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

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(),所以它有什么问题吗? (在编译期间,不是带有可选参数'扩展'的方法吗?)我错过了一个观点吗?我知道提出这样的问题可能会导致像“这是一个设计决定”或“它更容易实现”这样的答案,但在大多数情况下我只是忽略了一些东西。 :-)

2 个答案:

答案 0 :(得分:3)

我不是100%确定你的意思在编译期间,不是带有可选参数'扩展'的方法吗?但是我会说不。

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

所以每个

var b = new B();

在编译期间更改为

var b = new B(false);

为您创建了非附加构造函数。没有这样的事情:

public B() : this(false) {}

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

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

答案 1 :(得分:1)

考虑这个定义:

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;
    }
}

编译器不知道在泛型类中使用哪个构造函数。当然有办法解决这个问题。其中之一就是要求类具有无参数构造函数才有资格进行此类使用,正如您所描述的那样。