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

时间:2014-08-22 19:00:38

标签: 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;
        }
    }
}

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

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

3 个答案:

答案 0 :(得分:11)

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


The Language Design Notes for 21 April说(我以后没有找到任何参考):

  

在类型和主构造函数

上分离可访问性      

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

     

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

     

结论

     

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

所以,不,没有办法将主构造函数声明为protected。但是,正如已经指出的那样,public类的protectedabstract构造函数之间没有区别。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:5)

主要构造函数与一个类共享访问修饰符,因此只要您宣布它具有相同的访问级别,您就可以将其设为publicinternal 。您不能使用publicinternal主要构造函数进行protected课程。

但是,在你的情况下,即使构造函数是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;
}

您可以在Roslyn page on codeplex上详细了解新的C#功能,例如在本文档中:https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status