C#:使用抽象类强制构造函数签名?

时间:2014-09-29 22:07:29

标签: c# inheritance interface constructor abstract

我一直在寻找这个,因为我自然是健忘的,我认为构建一些东西(一个抽象的类,接口等?)将会强迫我实现某些代码在我写的课上。

特别是,我想强制一个新类总是有一个构造函数,它将单个参数键入为自身,以便更容易复制对象。我在其他地方看到过关于这个问题的文章/问题,但我不确定这个问题是否被提出过(至少我能找到)或者我根本不理解其他文章/问题来实现它。我提前道歉。

我对抽象类,接口等中的构造函数实际上做任何事都不感兴趣。我只想定义派生类中构造函数签名的要求。

我理想的课程看起来像这样:

public class GoodClass
{
    public GoodClass(GoodClass goodClass)
    {
        // copy components of goodClass to this instance
    }
}

所以,我首先开始研究接口,并开始阅读抽象类。我在想类似下面的代码会起作用,但是我得到了错误。我正在努力做甚么可能吗?有没有其他方法可以实现我的目标,而不会在我的显示器上贴上便利贴? :)

abstract class SelfConstructor
{
    abstract public SelfConstructor(SelfConstructor) { }
}

class NewClass : SelfConstructor
{
    //Required by SelfConstructor:
    public NewClass(NewClass newClass)
    {
        // copy components of newClass to this instance
    }
}

2 个答案:

答案 0 :(得分:1)

在C ++中,你所说的是一个复制构造函数,你实际上默认得到一个!

C#没有这个概念(当然你可以定义一个);但是,简单地实现ICloneableMSDN)会更容易(也更首选),这需要您实现同样的Clone方法。

而不是:

object myObj = new CloneableObject(otherObj);

你写道:

object myObj = otherObj.Clone();

可以做的另一件事是强制构造函数签名没有默认值:

public class BaseClass
{
    //No abstract constructors!
    public BaseClass(BaseClass copy)
    {
    }
}

现在,在派生时,必须在构造函数中使用该重载。没有什么会强制派生的签名,但至少你必须明确地使用它:

public class DerivedClass : BaseClass
{
    public DerivedClass() : base(this)
    {
    }
}

上面的例子清楚地表明它并没有“强迫”你拥有一个复制构造函数,但是像粘滞便笺一样,可以作为一个很好的提醒。

我肯定会去接口路由,因为那就是那里(你可以使用抽象实现!)。

请注意,如果您想免费获得副本,则可以利用Object.MemberwiseClone。所有对象都得到了这个,不需要任何接口。

答案 1 :(得分:1)

您可以编写一个识别此案例的ReSharper插件,如果它没有"复制构造函数"则会突出显示该类。这将是一个daemon stage,可以在编辑文件时对其进行处理,并添加高亮显示。您可以查看文件的抽象语法树,查找IConstructorDeclaration的所有实例,然后从ParameterDeclarations属性中获取构造函数的参数。您可以检查是否存在只有一个参数的构造函数,该参数与它声明的类的类型相同。

您可以通过获取构造函数的参数TypeUsage并尝试向下转换为IUserTypeUsage来比较类型。然后,您可以使用ScalarTypeName.Reference.Resolve()获取IDeclaredElement的实例。将其与班级IClassDeclaration.DeclaredElement进行比较,看看他们是否属于同一个实例。