"C#深度"中的抽象类实例化

Aag*_*age 18 c# code-contracts

我正在阅读Jon Skeet目前正在阅读的"C#深度",并且有一个示例描述代码契约,其中一个抽象类实现了一个接口,该接口具有作为接口的附带类,代码合同的术语:'Contract Class For'(我不会在这里详细介绍代码合同的运作方式.

界面(第467页):

[ContractClass(typeof(ICaseConverterContracts))]
public interface ICaseConverter
{
    string Convert(string text);
}
Run Code Online (Sandbox Code Playgroud)

抽象类:

[ContractClassFor(typeof(ICaseConverter))]
internal abstract class ICaseConverterContracts : ICaseConverter
{
    public string Convert(string text)
    {
         Contract.Requires(text != null);
         Contract.Ensures(Contract.Result<string>() != null);
         return default(string); // returns dummy value
    }

    // prevents instantiation
    private ICaseConverterContracts() { }

}
Run Code Online (Sandbox Code Playgroud)

(我根据书中的评论在代码中添加了注释)

我的问题:

当你无法实例化一个抽象类时,为什么有必要将私有构造函数添加到这个抽象类?我得不到什么?

Tim*_* S. 14

虽然abstract类不能直接实例化,private但构造函数上的访问修饰符(例如)在继承时很重要.通过构造函数private而不是默认构造函数,您可以创建它,以便不构造任何继承的类.因为这是唯一的构造函数时,有效地使类sealed,因为没有继承类(除非它是嵌套在ICaseConverterContracts)可以编译(在C#中,至少).

我猜的代码契约代码通过反射,或绕过构造存在的问题,一些其他的方式实例化类private.

  • 这是正确的,除了关于反射的部分.代码契约不会实例化类,而是工具直接读取IL. (4认同)

Dan*_*zey 7

将构造函数标记为私有也会阻止任何派生类被实例化:

public class Foo : ICaseConverterContracts
{
    public Foo()  // does not compile as the base class constructor is inaccessible
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这明确阻止您ICaseConverterContracts在任何情况下实例化类,因为它不是应该实例化的类.