我希望有一个类,它将具有索引器和字段数,如下例所示:
public abstract class ARecord
{
public abstract double this[int index] { get; }
public abstract int NumberOfFields { get; }
}
public class Record : ARecord
{
public double Field1{ get; private set; }
public double Field2{ get; private set; }
public override int NumberOfFields { get { return 2; } }
public Record(double[] records)
{
if (records.Count() != NumberOfFields) // PROBLEM IS HERE. WHEN CALLING THIS FROM DERIVED CLASS NumberOfFields=3!
throw new ArgumentException();
this.Field1= records[0];
this.Field2 = records[1];
}
public override double this[int index]
{
get { throw new NotImplementedException(); }
}
}
public class ChildRecord : Record
{
public double Field3 { get; private set; }
public override int NumberOfFields { get { return 3; } }
public ChildRecord(double[] records)
: base(new double[] { records[0], records[1] })
{
if (records.Count() != NumberOfFields)
throw new ArgumentException();
this.Field3 = records[2];
}
public override double this[int index]
{
get { throw new NotImplementedException(); }
}
}
public static class TestRecord
{
public static void CreateRecord()
{
var record = new ChildRecord(new double[]{1.0,1.5,2.5}); // Not working
}
}
此示例因NumberOfFields
构造函数内ChildRecord
内的多态调用Record
而崩溃。
据我所知,我可以new
使用override
来解决此问题,但在这种情况下,我无法在基类中将NumberOfFields
声明为abstract
(我需要的)。
解决此问题的正确方法是什么?设计有问题吗?
答案 0 :(得分:0)
你已经制定了这个方法,它不可能按预期工作。假设它做了(通过某种神奇的方式)以你认为应该的方式工作,并且你能够创建你的ChildRecord
:
var record = new ChildRecord(new double[] { 1.0, 1.5, 2.5 });
您期望record.NumberOfFields
的价值是多少?两三个?此特定对象不能是ChildRecord
NumberOfFields == 3
,同时Record
NumberOfFields == 2
。无论您将NumberOfFields
键入为record
,ARecord
还是Record
,都会获得实例化类的ChildRecord
实现结果。
换句话说:将ARecord.NumberOfFields
暴露给外界是没有意义的,因为没有一个正确的答案 - 它不是一个有意义的概念。
如果您放弃暴露它,您可以进行类似这样的验证(省略索引器和属性):
public abstract class ARecord
{
public abstract double this[int index] { get; }
}
public class Record : ARecord
{
private const int NumberOfFields = 2;
public Record(double[] records)
{
if (records.Count() != NumberOfFields)
throw new ArgumentException();
this.Field1 = records[0];
this.Field2 = records[1];
}
}
public class ChildRecord : Record
{
private const int NumberOfFields = 3;
public ChildRecord(double[] records)
: base(new double[] { records[0], records[1] })
{
if (records.Count() != NumberOfFields)
throw new ArgumentException();
this.Field3 = records[2];
}
}