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

C#6.0中的类是否可以具有受保护的主构造函数?,c#,c#-6.0,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 {

这一类:

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;
        }
    }
}
可以在C#中使用主构造函数重写为:

class Person(string firstName, string lastName)
{
    public string FirstName { get; } = firstName;
    public string LastName { get; } = lastName;
}
是否可以给主构造函数一个不同的修饰符,如下面的类中所示

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

否,主构造函数定义语法默认为构造函数的许多特征:

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


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

主构造函数与类共享访问修饰符,因此只要您声明的类具有相同的访问级别,您就可以将其
公开
内部
。您不能将
public
类与
internal
protected
主构造函数一起使用

然而,在您的情况下,即使构造函数是
public
也没有人能够直接调用它,因为您的类是
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;
}

您可以在上阅读有关新C#功能的更多信息,例如,在本文档中:

编辑:此回答涉及C#6.0的预发行版本。C#6.0的最终发行版根本没有主构造函数


比如(我后来没有发现任何关于这方面的参考):

类型和主构造函数上的独立可访问性 在某些情况下,您不希望类型的构造函数具有与类型相同的可访问性。一种常见的情况是,类型是公共的,但构造函数是私有的或受保护的,对象构造仅通过工厂公开

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

结论 不,没有优雅的方式来解决这个问题。这是一个很好的场景示例,开发人员应该回到正常的构造函数语法。根据前面的决定,我们已经尽力确保悬崖不会太陡


因此,不,没有办法将主构造函数声明为受保护的。尽管如此,正如已经指出的那样,
抽象类的
public
构造函数和
protected
构造函数之间没有区别。

我不理解这个用例,如果你将类抽象化,那么构造函数是否是公共的并不重要,因为你无论如何都必须继承这个类,授予您访问构造函数的权限。@Faisalsha您指的是一个具有普通C#version 5或更低版本构造函数的问题。不是primaray构造函数。@AlexSiepman你是说有一个
public static
方法进行构造吗?如果你将它保留为public,那么人们仍然不能调用它,因为你不能实例化一个抽象类。您仍然只能从子类调用它。没有完全回答这个问题。这不完全正确。。。有一种方法可以为主构造函数指定构造函数体。。。主构造函数也可以是
内部
私有
,只要整个类具有相同的访问修饰符…@MarcinJuraszek我相信这也不完全正确。你可以有一个单独的私有构造函数,而这个类可以是公共的。但是私有构造函数可以由主构造函数生成吗?我无法让这个例子工作。你能给C#6的文档添加一个链接吗?该文档描述了主构造函数如何拥有body?目前还没有规范。检查我答案中的最后一个链接。可能是您的VS版本还不支持它。CTP3的新功能(表达式体函数成员、运算符名称、空条件语句表达式)对我也不起作用。也许我需要在我的VisualStudio上使用CTP3版本来让这个空的身体工作。@MarcinJuraszek:自从VS2013发布以来,有很多版本的C#在运行,而且没有一个是我为应对这种情况而制作的C#6.0。