C# 在用于验证C中父构造函数参数的派生类中定义常量值的正确方法是什么#

C# 在用于验证C中父构造函数参数的派生类中定义常量值的正确方法是什么#,c#,polymorphism,derived-class,C#,Polymorphism,Derived Class,为了验证父构造函数中的参数,在派生类中定义常量值的正确方法是什么 给出以下示例: 公共抽象类多边形 { 受保护的抽象int VertexCount{get;} 公共线段[]边{get{/*…*/} 公共点2D[]顶点{get{/*…*/} 受保护多边形(点2D顶点) { 如果(顶点.Length!=顶点计数) 抛出了新ArgumentOutOfRangeException(…); } } 公共类三角形:多边形 { 受保护的覆盖int VertexCount{get;}=3; 公共三角形(Poi

为了验证父构造函数中的参数,在派生类中定义常量值的正确方法是什么

给出以下示例:

公共抽象类多边形
{
受保护的抽象int VertexCount{get;}
公共线段[]边{get{/*…*/}
公共点2D[]顶点{get{/*…*/}
受保护多边形(点2D顶点)
{
如果(顶点.Length!=顶点计数)
抛出了新ArgumentOutOfRangeException(…);
} 
}
公共类三角形:多边形
{
受保护的覆盖int VertexCount{get;}=3;
公共三角形(Point2D[]顶点):基(顶点){}
}
公共类四边形:多边形
{
受保护的覆盖int VertexCount{get;}=4;
公共四边形(Point2D[]顶点):基(顶点){}
}
显然,由于构造函数中的
虚拟成员调用
(是的,我理解这个警告,我不是在问这个问题),上述操作没有按预期工作

在我的逻辑(似乎有缺陷)中,
VertexCount
Polygon
类的一个功能(因为
顶点
的数组的固定大小将由Polygon类中的定义),并且根据派生类的不同而不同(因此需要在派生类中定义)

派生类需要定义
VertexCount
的值,因为它特定于派生类,但是基类不知道派生类。这就是“抽象int”的原因,以确保派生类重写它。此外,
VertexCount
是一个属性,因为字段c不是抽象的。但是,它也应该是常数(因为三角形的边总是3,四边形的边总是4)

最后,在基本构造函数中抛出的
异常
的消息应该类似于:

if(vertexts.Length!=VertexCount)
抛出新ArgumentOutOfRangeException(顶点名称),
消息:$“A{this.ToString()}正好需要{VertexCount}个顶点,收到{vertexts.Length}”);
当然,“this.ToString()”部分将在基类而不是派生类的上下文中调用(这里可能可以使用反射解决方案)

因此,有了所有这些,另一种选择是在基类中放弃构造函数,在派生类中为
VertexCount
创建一个常量,并初始化和设置派生类构造函数中的所有值。这似乎会在派生类中产生大量重复的代码(在上面的示例中可能不是这样,因为从技术上讲,我只在每个示例中复制了2行代码,但是当构造函数变得更重时会发生什么情况)


用最少的重复代码做这件事的“正确”方法是什么?

在重新阅读Peter Duniho的评论后,我提出了这个重构,我认为这是一个更好的解决方案。(我认为问题的措辞有点模糊/主观,因为最初的逻辑是错误的,我正在寻找对我的逻辑的修正,而不是确切知道问题是什么以及如何解决问题)

问题是:

在派生类中定义常量值的正确方法是什么 用于验证C中父构造函数中的参数#

简而言之,你不需要。在上面的示例代码中定义一个常量是没有必要的。它根本不需要存储,它不是代码的其他部分(在本例中)需要的东西,它是一个值,只有在实例化时才需要验证

公共类三角形:多边形
{
公共三角形(Point2D[]顶点):基(顶点,3){}
}
公共类四边形:多边形
{
公共四边形(Point2D[]顶点):基(顶点,4){}
}
我试图实现的另一个目标(使用原始示例),是早期验证。换句话说,如果没有为派生类型传递正确数量的顶点,我希望在对无效对象执行任何其他初始化步骤之前停止初始化。在给定示例中,派生构造函数中的默认构造函数和验证为空(或者甚至从派生构造函数调用包含在基方法中的验证方法)也可以,不将顶点传递给基,而是验证并在派生构造函数中设置它们。然而,关键是早期验证,如果基类对(pre)做了大量工作(更复杂的类),该怎么办在进入派生类之前初始化对象。在进行任何处理(包括初始化)之前,验证代码确实属于该类

通过将(与验证相关的)值传递给基本构造函数,可以在开始时进行验证,以便在验证失败时防止其他代码运行

受保护多边形(Point2D[]顶点,int-expectedVerticesCount)
{
//不要麻烦初始化对象,数据无效!
if(顶点数.Length!=expectedVerticesCount)
抛出新ArgumentOutOfRangeException(/*…*/);
//数据有效,继续初始化
顶点=顶点;
}
“正确”是旁观者的看法。例如,我认为基于“虚拟财产”的方法无论做什么都有缺陷(你的或下面的提案)。您应该有
受保护的
构造函数,派生类型可以向其传递适当的常量值。该值可以存储在
只读
字段中。不要担心额外的4个字节…这是无关紧要的。更重要的是保持代码简单、安全且易于推理(即,您不必查看