2015-11-05 94 views
1

我有一個類繪製三種類型的圖表,我想通過函數public void GetData(PlotModel PlotModel)更新它。主要問題是每個系列(AreaSeries,CandleStickSeries,HighLowSeries)都有不同的接口。我如何更新函數public void GetData(PlotModel PlotModel)中的不同類型。我應該使用Activator?通用?創建未知類型的實例

我覺得有點像壞主意:

public void GetData(PlotModel PlotModel) { 
    while(true) { 
     System.Threading.Thread.Sleep(1000); 
     // Add new Item? 
     switch(PlotModel.Series.First().ToString()) { 
      case "OxyPlot.Series.AreaSeries": 
       Console.WriteLine("AreaSeries"); 
       break; 
      case "OxyPlot.Series.CandleStickSeries": 
       Console.WriteLine("CandleStickSeries"); 
       break; 
      case "OxyPlot.Series.HighLowSeries": 
       Console.WriteLine("HighLowSeries"); 
       break; 
     } 
    } 
} 

代碼:

namespace WpfApplication20 { 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    /// 
    public partial class MainWindow : Window { 
     public MainWindow() { 
      InitializeComponent(); 
      DataContext = new PlotClass(); 
     } 
    } 
    public class PlotClass { 
     public PlotModel PlotModel { get; set; } 
     public PlotClass() { 
      PlotModel = new PlotModel(); 
      DrawCandleChart(PlotModel); 
      UpdateChartAsync(PlotModel); 
     } 
     public void DrawSimpleChart(PlotModel PlotModel) { 
      Random rnd = new Random(); 
      LineSeries LS = new LineSeries(); 
      for (int i=0;i<10;i++) { 
       LS.Points.Add(new DataPoint(i,rnd.NextDouble())); 
      } 
      PlotModel.Series.Add(LS); 
      PlotModel.InvalidatePlot(false); 
     } 

     public void DrawCandleChart(PlotModel PlotModel) { 
      Random rnd = new Random(); 
      CandleStickSeries CSS = new CandleStickSeries(); 
      for (int i=0;i<10;i++) { 
       CSS.Items.Add(new HighLowItem { Close = rnd.NextDouble(), High = rnd.NextDouble(), Low = rnd.NextDouble(), Open = rnd.NextDouble(), X = i }); 
      } 
      PlotModel.Series.Add(CSS); 
      PlotModel.InvalidatePlot(false); 
     } 

     public void DrawHighLowChart(PlotModel PlotModel) { 
      Random rnd = new Random(); 
      HighLowSeries HLS = new HighLowSeries(); 
      for (int i = 0; i < 10; i++) { 
       HLS.Items.Add(new HighLowItem { Close = rnd.NextDouble(), High = rnd.NextDouble(), Low = rnd.NextDouble(), Open = rnd.NextDouble(), X = i }); 
      } 
      PlotModel.Series.Add(HLS); 
      PlotModel.InvalidatePlot(false); 
     } 

     public void UpdateChartAsync(PlotModel PlotModel) { 
      Action<PlotModel> Update = new Action<PlotModel>(GetData); 
      IAsyncResult result = Update.BeginInvoke(PlotModel, null, null); 
     } 

     public void GetData(PlotModel PlotModel) { 
      while(true) { 
       System.Threading.Thread.Sleep(1000); 
       // Add new Item? 
      } 
     } 
    } 
} 
+0

聽起來你的函數更新它們應該屬於類本身。 –

+1

您應該使用計時器而不是無限循環。它並不清楚你的意思是添加一個新項目,因爲你的代碼並沒有真正顯示出不同的界面,它很難告訴你如何使用代理或適配器來解決問題。 –

+0

使用動態屬性可能會增加性能。你有一個所有模型都來自哪個基礎接口?你可以在那裏添加一個Draw方法。然後,只要您的主要方法接受了該接口,就可以在該對象上調用Draw方法。 – SILENT

回答

3

C#4及以上提供的這樣的處理情況的好方法:使用CAST dynamic,和呼叫每個亞型有一個過載的方法,如下所示:

private void Process(AreaSeries arSer) { 
    ... 
} 
private void Process(CandleStickSeries csSer) { 
    ... 
} 
private void Process(HighLowSeries hlSer) { 
    ... 
} 
... 
while(true) { 
    System.Threading.Thread.Sleep(1000); 
    Process((dynamic)PlotModel.Series.First()); 
    //  ^^^^^^^^^ 
} 

dynamic會使「魔術」發生:C#將檢查運行時類型PlotModel.Series.First(),並將其分派到您提供的三種方法之一Process

有這種方法的危險:如果PlotModel.Series.First()恰好匹配任何重載的,你會得到一個運行時異常。編譯器不能執行靜態分析來告訴你,你的調用不會成功。考慮爲您的圖的公共超類添加一個全能方法,以便您可以更優雅地處理意外的子類型。