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

本文关键字:受保护 构造函数 有一个 | 更新日期: 2023-09-27 18:19:05

这个类:

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

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

EDIT:这个答案讨论的是c# 6.0的预发布版本。c# 6.0的最终发布版本根本没有主构造函数。


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

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

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

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

结论

。没有什么优雅的方法可以解决这个问题。这是一个很好的例子,在这种情况下,开发人员应该退回到正常的构造函数语法。根据上面的决定,我们已经尽了最大的努力来确保悬崖不会太陡。

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

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

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

等。

(这里讨论的是一个尚未发布的特性,可能会在其他版本中发生变化)

主构造函数与类共享访问修饰符,因此您可以将其设置为publicinternal,只要您声明的类具有相同的访问级别。你不能有public类与internalprotected主构造函数。

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

你可以在codeplex的Roslyn页面上阅读更多关于c#新特性的信息,例如:https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status