2012-04-10 80 views
2

我有兩個從基類BaseParser繼承的解析器類。我想在另一個Monitor類中使用任何一個類作爲參數。解析器類CS600和TCH600都有兩個屬性,RawDataList和SummaryDataList。 CS600類的RawDataList返回一個List(的CS600Data); TCH600 RawDataList返回一個List(TCH600Data)。 SummaryDataList在每個Parser類中返回相似的類。 CS600Data和TCH600Data從基類BaseData派生。 BaseParser還具有RawDataList(列表(的BaseData))和SummaryDataList(列表(BaseSummaryData的))使用具有不同返回類型的多態子類

Monitor類具有私有字段,_thisParser其可以是兩個混凝土解析器的上方。我希望能夠在Monitor類中調用並使用_thisParser的RawDataList和SummaryDataList,但是當我構造具體的Parser類時,Visual Studio指出CS600的RawDataList屬性不能覆蓋BaseParser的RawDataList屬性,因爲它們的返回值不同類型。

我認爲,自CS600Data派生自BaseData(但也增加了一些自己的新屬性),我可以在任何地方使用CS600Data BaseData。我誤解了什麼?我怎樣才能正確構造這些類?

Public MustInherit Class BaseParser 

    Protected _rawDataList As List(Of RawGasData.BaseData) 
    Public MustOverride ReadOnly Property RawDataList() As List(Of RawGasData.BaseData) 

    Protected _summaryDataList As List(Of SummaryGasData.BaseSummaryData) 
    Public MustOverride ReadOnly Property SummaryDataList() As List(Of SummaryGasData.BaseSummaryData) 

    Public Event GasDataCreated(ByVal sender As Object, ByVal e As EventArgs) 

    Public Sub New() 
    End Sub 

    Public Sub New(ByVal dataFilePath As String, ByVal unit As String) 
     Load(dataFilePath, unit) 
    End Sub 

    Public Sub Load(ByVal dataFilePath As String, ByVal unit As String) 
     Dim contents = My.Computer.FileSystem.ReadAllText(dataFilePath) 
     ParseRawData(contents) 
     GenerateSummaryData(contents, unit) 
     RaiseEvent GasDataCreated(Me, EventArgs.Empty) 
    End Sub 

    Protected MustOverride Sub ParseRawData(ByVal fileContents As String) 

    Protected MustOverride Sub GenerateSummaryData(ByVal fileContents As String, ByVal unit As String) 

End Class 

Public Class CS600Parser 
    Inherits BaseParser 

    Shadows _rawDataList As List(Of RawGasData.CS600Data) 
    'Cannot override base class' RawDataList - differ by their return types 
    Public Overrides ReadOnly Property RawDataList() As List(Of RawGasData.CS600Data) 
     Get 
      Return _rawDataList 
     End Get 
    End Property 

    Shadows _summaryDataList As List(Of SummaryGasData.CS600SummaryData) 
    'Cannot override base class' SummaryDataList - differ by their return types 
    Public Overrides ReadOnly Property SummaryDataList() As List(Of SummaryGasData.CS600SummaryData) 
     Get 
      Return _summaryDataList 
     End Get 
    End Property 

    Protected Overrides Sub ParseRawData(ByVal fileContents As String) 
     Dim data = From d In fileContents.Trim.Split(CChar(vbCrLf)) _ 
        Let fields = d.Split(","c).Select(Function(s) s.Trim) _ 
        Select New RawGasData.CS600Data With { _ 
         .SampleNumber = fields(0), _ 
         .UserID = fields(1), _ 
         .CarbonValue = CDbl(fields(2)), _ 
         .SulfurValue = CDbl(fields(3))} 

     _rawDataList = data.ToList 

    End Sub 

    Protected Overrides Sub GenerateSummaryData(ByVal fileContents As String, ByVal unit As String) 
     Dim groupedData = From d In _rawDataList _ 
          Group By d.SampleNumber Into Group _ 
          Select New SummaryGasData.CS600SummaryData With { _ 
          .DataTimeStamp = Now, _ 
          .SampleNumber = SampleNumber, _ 
          .UserID = Group.First.UserID, _ 
          .CarbonAverage = Group.Select(Function(s) s.CarbonValue).Average, _ 
          .CarbonUnit = unit, _ 
          .SulfurAverage = Group.Select(Function(s) s.SulfurValue).Average, _ 
          .SulfurUnit = unit} 

     _summaryDataList = groupedData.ToList 

    End Sub 

End Class 

Public Class TCHParser 
    Inherits BaseParser 

    Shadows _rawDataList As List(Of RawGasData.TCH600Data) 
    'Cannot override base class' RawDataList - differ by their return types 
    Public Overrides ReadOnly Property RawDataList() As List(Of RawGasData.TCH600Data) 
     Get 
      Return _rawDataList 
     End Get 
    End Property 

    Shadows _summaryDataList As List(Of SummaryGasData.TCH600SummaryData) 
    'Cannot override base class' SummaryDataList - differ by their return types 
    Public Overrides ReadOnly Property SummaryDataList() As List(Of SummaryGasData.TCH600SummaryData) 
     Get 
      Return _summaryDataList 
     End Get 
    End Property 

    Protected Overrides Sub ParseRawData(ByVal fileContents As String) 
     Dim data = From d In fileContents.Trim.Split(CChar(vbCrLf)) _ 
     Let fields = d.Split(","c).Select(Function(s) s.Trim) _ 
     Select New RawGasData.TCH600Data With { _ 
      .SampleNumber = fields(0), _ 
      .UserID = fields(1), _ 
      .OxygenValue = CDbl(fields(2)), _ 
      .NitrogenValue = CDbl(fields(3)), _ 
      .HydrogenValue = CDbl(fields(4)), _ 
      .MassUsed = CDbl(fields(5))} 

     _rawDataList = data.ToList 

    End Sub 

    Protected Overrides Sub GenerateSummaryData(ByVal fileContents As String, ByVal unit As String) 
     Dim groupedData = From d In _rawDataList _ 
          Group By d.SampleNumber Into Group _ 
          Select New SummaryGasData.TCH600SummaryData With { _ 
          .DataTimeStamp = Now, _ 
          .SampleNumber = SampleNumber, _ 
          .UserID = Group.First.UserID, _ 
          .OxygenAverage = Group.Select(Function(s) s.OxygenValue).Average, _ 
          .OxygenUnit = unit, _ 
          .NitrogenAverage = Group.Select(Function(s) s.NitrogenValue).Average, _ 
          .NitrogenUnit = unit, _ 
          .HydrogenAverage = Group.Select(Function(s) s.HydrogenValue).Average, _ 
          .HydrogenUnit = unit} 

     _summaryDataList = groupedData.ToList 
    End Sub 


End Class 


Public MustInherit Class BaseData 
    Implements IGasData 

    Private _massUsed As Double 
    Public Property MassUsed() As Double Implements IGasData.MassUsed 
     Get 
      Return _massUsed 
     End Get 
     Set(ByVal value As Double) 
      _massUsed = value 
     End Set 
    End Property 

    Private _sampleNumber As String 
    Public Property SampleNumber() As String Implements IGasData.SampleNumber 
     Get 
      Return _sampleNumber 
     End Get 
     Set(ByVal value As String) 
      _sampleNumber = value 
     End Set 
    End Property 

    Private _userID As String 
    Public Property UserID() As String Implements IGasData.UserID 
     Get 
      Return _userID 
     End Get 
     Set(ByVal value As String) 
      _userID = value 
     End Set 
    End Property 
End Class 

Public Class CS600Data 
    Inherits BaseData 


    Private _carbonValue As Double 
    Public Property CarbonValue() As Double 
     Get 
      Return _carbonValue 
     End Get 
     Set(ByVal value As Double) 
      _carbonValue = value 
     End Set 
    End Property 


    Private _sulfurValue As Double 
    Public Property SulfurValue() As Double 
     Get 
      Return _sulfurValue 
     End Get 
     Set(ByVal value As Double) 
      _sulfurValue = value 
     End Set 
    End Property 

End Class 

Public Class TCH600Data 
    Inherits BaseData 

    Private _oxygenValue As Double 
    Public Property OxygenValue() As Double 
     Get 
      Return _oxygenValue 
     End Get 
     Set(ByVal value As Double) 
      _oxygenValue = value 
     End Set 
    End Property 


    Private _nitrogenValue As Double 
    Public Property NitrogenValue() As Double 
     Get 
      Return _nitrogenValue 
     End Get 
     Set(ByVal value As Double) 
      _nitrogenValue = value 
     End Set 
    End Property 


    Private _hydrogenValue As Double 
    Public Property HydrogenValue() As Double 
     Get 
      Return _hydrogenValue 
     End Get 
     Set(ByVal value As Double) 
      _hydrogenValue = value 
     End Set 
    End Property 

End Class 
+0

你應該用適當的語言(VB?)標記問題,而不是用'visual-studio',除非問題實際上處理VS.你還應該發佈你的課程代碼,並指出你有問題的地方。 – 2012-04-10 00:57:57

+0

謝謝,@KendallFrey;我進行了建議的更改 – blueshift 2012-04-10 10:30:55

回答

1

你重寫列表屬性,如RawDataList,應該是抽象基類的類型(或更好,但IGasData),而不是派生類的多態性工作。如果您發現使BaseDataIGasData類型的列表出現問題,您可能需要檢查您的設計是否符合Liskov Substitution Principle

的簡化圖示,其編譯和運行得很好(VB.Net 2010):

Sub Main  
    Dim parser As BaseParser = New TCHParser() 
    Console.WriteLine(parser) 
End Sub 

Public MustInherit Class BaseData  
    Public Property SampleNumber() As String 
End Class 

Public Class TCH600Data 
    Inherits BaseData 

    Public Property OxygenValue() As Double 
End Class 

Public MustInherit Class BaseParser 
    Public MustOverride ReadOnly Property RawDataList As List(of BaseData) 
End Class 

TCHParser作品就好重寫RawDataList屬性。另外,我不確定爲什麼抽象基類有一個Protected _rawDataList字段。刪除它,你不必擔心在派生類型中映射該字段。

Public Class TCHParser 
    Inherits BaseParser 

    ' Populate the list just so we can test easily. 
    Public Sub New() 
     Dim data As New List(Of BaseData) 
     data.Add(New TCH600Data With { 
      .SampleNumber = "1", _ 
      .OxygenValue = 1.5d }) 

     data.Add(New TCH600Data With { 
      .SampleNumber = "2", _ 
      .OxygenValue = 2.5d }) 

     _rawDataList = data 
    End Sub 

    Private _rawDataList As List(of BaseData) 
    Public Overrides ReadOnly Property RawDataList As List(of BaseData) 
     Get 
      Return _rawDataList 
     End Get 
    End Property 
End Class 
+0

謝謝,@Matt,但它不能解決返回類型問題。我將重新訪問LSP以查看我缺少的內容。 – blueshift 2012-04-10 15:40:23

+0

@blueshift,我已經更新了我的示例以更完整。 – Matt 2012-04-10 18:52:55

+0

非常好!謝謝,@Matt;這真的解釋瞭如何解決這個問題。 – blueshift 2012-04-11 16:54:11