【发布时间】:2011-07-05 16:27:07
【问题描述】:
我正在使用什么:
VB.NET、NET 3.5、OpenXML SDK 2.0
我想做的事:
我正在为我的应用程序创建一个 xlsx 读取器/写入器(基于 OpenXML SDK 2.0)。我想读取 xlsx 文件并将每行中包含的数据存储在 DTO/PONO 中。此外,我想读取 xlsx 文件,然后对其进行修改并保存。
我的想法:
现在我的问题不在于 OpenXML SDK,我可以做我需要做的。
我的问题是如何构建我的组件。具体来说,我在电子表格的最低级别(单元格)存在多态性问题。
Excel/OpenXML 中的单元格可以关联不同类型的数据。如时间、日期、数字、文本或公式。在从电子表格读取/写入电子表格时,需要以不同的方式处理这些不同的类型。
我决定为所有子类型(如 TextCell、NumberCell、DateCell 等)提供一个通用接口。
现在,当我从电子表格中读取单元格时,方法/工厂可以决定创建哪种类型的单元格。
现在因为单元格是实际实现的抽象,所以它不知道/不需要知道它是什么类型。为了编写/修改单元格,我通过在要保留的单元格上调用 .write(ICellWriter) 来解决此问题。由于单元本身知道它包含什么类型的数据,它知道它需要调用 ICellWriter 的哪个方法(静态多态性)。
我的问题:
写入 xlsx 文件没有问题。我的问题是,如何在不使用类型检查的情况下将数据从单元格中取出到 DTO/PONO 中 -> If TypeOf variable is ClassX then doesomething End If。由于方法/属性必须具有不同的签名,并且不允许仅使用不同的返回类型进行区分。
编辑:
对象(指单元格)的持有者(集合,在这种情况下是表格/电子表格的一行)不知道具体的实现。因此,对于编写单元格,我将其传递给 Cellwriter。此 Cellwriter 具有重载方法,例如 Write(num as Integer)、Write(text as String)、Write(datum as Date)。将这个传递给它的单元格对象然后使用它所拥有的数据类型调用Write() 方法。这是可行的,因为没有返回值被传回。
但是当我需要返回具体的数据类型时该怎么办?
有什么想法、建议、见解?
谢谢
编辑:
词汇表:
- DTO:数据传输对象
- PONO:普通旧 .Net 对象
- xlsx:指excel工作簿文件的文件结尾
编辑:
Cell“子类型”实现了一个通用接口,而不是从一个通用超类继承。
编辑:
在考虑了这个问题之后,我开始意识到,如果不反思或不知道我期待什么类型的细胞,这是不可能的。基本上,我试图重新创建一个电子表格或具有类似功能的东西,而且对于我的需要来说太抽象/可配置了。感谢您花费时间和精力来写答案。我接受了最接近我意识到的答案。
【问题讨论】:
-
我在问题的末尾添加了一个词汇表,希望对您有所帮助。
-
我知道这并不能直接回答问题,但您为什么不直接使用 ado.net 读取 excel 文件?有什么特殊情况你不能这样做吗?
-
@Dom:也许 ado.net 可能是一个选择 :)。您可以使用 ado.net 修改“命名范围”的引用吗?我认为 ado.net 将在您将新行插入工作表时使用正确的格式。
-
我使用了一个将 writer 作为第一个参数的扩展方法。然后我简单地为每种可能进入的数据类型创建了一个函数。 {Decimal, Double, and Float} 称为公共私有 WriteCell;串另一个;依此类推,日期时间等等。然后我对枚举使用了通用的 public WriteCell(Of T As Structure, IConvertable, ...) 。最通用的是 WriteCell(writer, obj As Object, rowIndex, columnIndex, Optional styleIndex As Integer = 0),它将转换为相应的类型。然后 ExportDataTableToSpreadsheet,将每个单元格写入该 Object WriteCell
-
另一个想法是使用 T4 模板(免费)或其他代码生成工具。这将为您提供类似 C++ 的模板而不是泛型。这可以绕过我必须经历的所有打字(vs2010 有更好的支持)。
标签: vb.net oop .net-3.5 polymorphism