C#6.0中的类可以有受保护的主构造函数吗?

Ale*_*man 21 c# c#-6.0

这个班:

class Person 
{
    public Person(string firstName, string lastName)
    {
        _firstName = FirstName;
        _lastName = lastName;
    }

    private readonly string _firstName; // Make it really immutable
    public string FirstName
    {
        get
        {
            return _firstName;
        }
    }

    private readonly string _lastName; // Make it really immutable
    public string LastName
    {
        get
        {
            return _lastName;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

可以使用构造函数在C#6.0版中重写为:

class Person(string firstName, string lastName)
{
    public string FirstName { get; } = firstName;
    public string LastName { get; } = lastName;
}
Run Code Online (Sandbox Code Playgroud)

是否可以为主构造函数提供不同的修饰符,如下面的类?

abstract class Person 
{
    protected Person(string firstName, string lastName)
    {
        _firstName = FirstName;
        _lastName = lastName;
    }

    private readonly string _firstName; // Make it really immutable
    public string FirstName
    {
        get
        {
            return _firstName;
        }
    }

    private readonly string _lastName; // Make it really immutable
    public string LastName
    {
        get
        {
            return _lastName;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

svi*_*ick 11

编辑:这个答案谈论C#6.0的预发布版本.C#6.0的最终发行版本根本没有主要构造函数.


4月21日的语言设计说明(我后来没有发现任何参考):

在类型和主构造函数上分离可访问性

在某些情况下,您不希望类型的构造函数具有与类型相同的可访问性.一个常见的情况是类型是公共的,但构造函数是私有的或受保护的,对象构造只能通过工厂公开.

我们应该发明语法,以便主构造函数可以获得与其类型不同的可访问性吗?

结论

没有.没有优雅的方法来解决这个问题.这是开发人员应该回归到正常构造函数语法的一个很好的例子.通过上述决定,我们已尽最大努力确保悬崖不会太陡峭.

所以,不,没有办法将主构造函数声明为protected.虽然,正如已经指出的那样,类publicprotected构造函数之间没有区别abstract.


Ben*_*igt 5

不,主构造函数定义语法默认构造函数的许多特性:

  • 它总是公开的
  • 它除了成员初始化之外从未在体内有任何东西(看起来这在不同的预览版本之间有所不同,并且还没有人知道最终的C#6.0规范中会有什么)
  • 将从派生类的所有构造函数中调用相同的基础构造函数(因为其余的构造函数转发到主构造函数)

等等

(这讨论了一个尚未发布的功能,它可能会在其他版本中更改)

  • 这不是完全正确的......有一种方法可以为主构造函数指定构造函数体...也可以是主要构造函数`internal`或`private`,只要整个类具有相同的访问修饰符... (2认同)

Mar*_*zek 5

主构造函数与一个类共享访问修饰符,因此您可以创建它,public或者 internal,只要您声明它具有相同的访问级别.你不能拥有publicinternalprotected主要构造函数.

但是,在你的情况下,即使构造函数public没有人也可以直接调用它,因为你的类是abstract,你不能实例化一个抽象类.您必须实例化继承它的类,而不是abstract.

PS我知道这不是问题的一部分,但我看到你已经接受了一个答案,其中包含有关主要构造函数的其他信息,但事实并非如此.主构造函数可以有正文!

(...)可以简单地通过将它包含在声明类型内的花括号中来指定主构造函数体:

public class Customer(string first, string last)
{
    {
        if (first == null) throw new ArgumentNullException("first");
        if (last == null) throw new ArgumentNullException("last");
    }

    public string First { get; } = first;
    public string Last { get; } = last;
}
Run Code Online (Sandbox Code Playgroud)

您可以在Codeplex上的Roslyn页面上阅读有关新C#功能的更多信息,例如在本文档中:https://roslyn.codeplex.com/wikipage?title = Language = 20Feature%20Status