0

我正在编写一些软件,可以自动从实验中收集数据,并且需要一些帮助来表达我的业务对象之间的关系。

我有一个名为Experiment的类型,一个名为 的类型Sample和一个未实现的RunOnSample方法,Experiment其中应该接受该Sample类型的派生并将数据填充到其中:

Public MustInherit Class Experiment
    Public Property TestDate As Date
    Public Property Experimenter As String

    Public MustOverride Sub RunOnSample(sample As Sample)
End Class

Public MustInherit Class Sample
    Public Property UnitLotCode As String
End Class

这两种类型实际上都不是可实例化的,因为我有不同的实验(由 的子类型表示Experiment)生成各种数据。每个实验都有一个匹配的子类型,Sample该子类型具有存储实验生成的数据的属性。请注意,基类是必需的,因为所有实验都有一些共同的属性,并且将为所有样本记录一些数据。

例如,aThicknessExperiment测量厚度数据并扫描批次代码,然后将此数据填写到 a 中ThicknessSample

Public Class ThicknessExperiment
    Public Overrides Sub RunOnSample(sample As ThicknessSample)
        Dim data = GetDataFromMeasurementDevice()

        sample.UnitLotCode = data.LotCode
        sample.Thickness = data.Thickness
    End Sub
End Class

Public MustInherit Class ThicknessSample
    Public Property Thickness As Single
End Class

这里的问题是参数的类型是编译器无法接受的;的实现RunOnSample必须接受Sample,而不是ThicknessSample(或任何其他子类型Sample)。大概这是因为,如果编译器让我按照自己的方式进行,派生的实验将不再具有与父类相同的接口,这将是非多态的。

我能想到的解决这个问题的唯一方法是Sample在使用它之前将参数转换为方法内部的适当子类型。有没有更好的方法来实现我的目标?最好是一种保持XYZExperiment.RunOnSample方法与XYZSample参数的强类型关联的方法?

4

1 回答 1

1

首先,我想说的是,作为个人喜好一些经验,我学会了不要将继承用于代码重用或公共属性,而只是为了从多态中受益,所以我会将这些公共数据属性提取到一个新类并为不同的属性使用字典,然后使用委托(组合)来存储某个样本的数据。无论如何,我建议的解决方案涉及使用泛型,因此您可以执行以下操作:

public abstract class Experiment<TSample>
            where TSample : Sample
        {
            private DateTime experimentDate;
            private string Experimenter;

            public abstract void RunOnSample(TSample sample);
        }

        public class ThicknessExperiment : Experiment<ThicknessSample>
        {

            public override void RunOnSample(ThicknessSample sample)
            {
                // sample.lotcode = "43";
                // sample.data1 = "343";
                // sample.data2 = "43";

            }
        }

        public abstract class Sample
        {
            public string lotcode;

        }

        public class ThicknessSample : Sample
        {
            public string data1;
            public string data2;
        }
于 2013-07-10T23:56:58.197 回答