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

本文关键字:构造函数 抽象类 | 更新日期: 2023-09-27 18:25:04

我已经为此搜索了一段时间,因为我天生健忘,我认为构建一些东西(抽象类、接口等?)会迫使我在正在编写的类中实现某些代码会很好。

特别是,我想强制一个新类始终具有一个构造函数,该构造函数将一个类型化的参数作为自身,以便更容易复制对象。我在其他地方看到过关于这一点的文章/问题,但我不确定这个特定的问题是否被问过(至少我能找到),或者我对其他文章/问题的理解不够,无法意识到这一点。我提前道歉。

我对在抽象类、接口等中使用构造函数实际上做任何事情都不感兴趣。我只是对在派生类中定义构造函数签名的需求感兴趣。

我理想的班级是这样的:

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

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

如果没有"复制构造函数",您可以编写一个ReSharper插件来识别这种情况并突出显示该类。这将是一个守护进程阶段,它将在编辑文件时处理文件,并添加高亮显示。您可以查看文件的抽象语法树,查找IConstructorDeclaration的所有实例,然后从ParameterDeclarations属性中获取构造函数的参数。您可以检查是否有一个构造函数只有一个参数,并且该参数与它在中声明的类的类型相同。

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

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

C#没有这个概念(当然你可以定义一个);然而,简单地实现ICloneable(MSDN)更容易(也是更可取),它需要您实现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。所有对象都得到了这个,不需要接口。