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
}
}
如果没有"复制构造函数",您可以编写一个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
。所有对象都得到了这个,不需要接口。