如何解决用于在报告进度的同时导出各种格式的对象的代码,使其更具扩展性
说明
WinForms应用程序具有导出各种格式的以下类型对象的功能:
class Item
{
public int id { get; set; }
public string description { get; set; }
}
单击窗口中的按钮,将显示SaveFileDialog
,当前它提供了以.txt,.csv或.xlsx格式保存数据的选项。由于有时有成百上千个对象,并且UI不应冻结,因此使用Task
来运行此操作。此实现有效,但可以改进。
代码
public partial class ExportWindow : Form
{
// objects to be exported
List<Item> items;
// event handler for the "Export" button click
private async void exportButton_click(object sender,System.EventArgs e)
{
SaveFileDialog exportDialog = new SaveFileDialog();
exportDialog.Filter = "Text File (*.txt)|*.txt|Comma-separated values file (*.csv)|*.csv|Excel spreadsheet (*.xlsx)|*.xlsx";
exportDialog.CheckPathExists = true;
DialogResult result = exportDialog.ShowDialog();
if (result == DialogResult.OK)
{
var ext = System.IO.Path.GetExtension(saveExportFileDlg.FileName);
try
{
// update status bar
// (it is a custom control)
statusBar.text("Exporting");
// now export it
await Task.Run(() =>
{
switch (ext.ToLower())
{
case ".txt":
saveAsTxt(exportDialog.FileName);
break;
case ".csv":
saveAsCsv(exportDialog.FileName);
break;
case ".xlsx":
saveAsExcel(exportDialog.FileName);
break;
default:
// shouldn't happen
throw new Exception("Specified export format not supported.");
}
});
}
catch (System.IO.IOException ex)
{
statusBar.text("Export failed");
logger.logError("Export failed" + ex.Message + "\n" + ex.StackTrace);
return;
}
}
}
private delegate void updateProgressDelegate(int percentage);
public void updateProgress(int percentage)
{
if (statusBar.InvokeRequired)
{
var d = updateProgressDelegate(updateProgress);
statusBar.Invoke(d,percentage);
}
else
{
_updateProgress(percentage);
}
}
private void saveAsTxt(string filename)
{
IProgress<int> progress = new Progress<int>(updateProgress);
// save the text file,while reporting progress....
}
private void saveAsCsv(string filename)
{
IProgress<int> progress = new Progress<int>(updateProgress);
using (StreamWriter writer = StreamWriter(filename))
{
// write the headers and the data,while reporting progres...
}
}
private void saveAsExcel(string filename)
{
IProgress<int> progress = Progress<int>(updateProgress);
// EPPlus magic to write the data,while reporting progress...
}
}
问题
如何对其进行重构以使其更具扩展性?就是说,如果我想增加对更多文件类型的支持,则可以轻松快捷地进行修改。 switch语句可能会很长。本质上,如何遵守开放/封闭原则?
解决方法
为每个扩展名创建类可能是一种方法。 除了通过列表或使用反射来进行迭代之外,因此,如果要添加对新扩展的支持,则只需创建一个新类,而不要触摸ExportWindow
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。