开发者

How to get differing value type out of an concrete implementation if only Interface / abstract class is known?

开发者 https://www.devze.com 2023-02-14 08:37 出处:网络
what I am using: VB.NET, NET 3.5, OpenXML SDK 2.0 what I want to do: I am creating an xlsx reader / writer for my application (based on OpenXML SDK 2.0). I want to read xlsx files and store the data

what I am using:

VB.NET, NET 3.5, OpenXML SDK 2.0

what I want to do:

I am creating an xlsx reader / writer for my application (based on OpenXML SDK 2.0). I want to read xlsx files and store the data contained in each row in a DTO/PONO. Further I want to read the xlsx file and then modify it and save it.

my thoughts:

Now my problem is not with the OpenXML SDK, I can do what I need to do.

My problem is on how to structure my components. Specifically I have problems with the polymorphism at the lowest level of a Spreadsheet, the cell.

A cell in Excel/OpenXML can have different types of data associated with it. Like a Time, Date, Number, Text or Formula. These different type need to be handled differently when read/written from/to a spreadsheet.

I decided to have a common interface for all subtypes like TextCell, NumberCell, DateCell etc.

Now when I read the cell from the spreadsheet the Method/Factory can decide which type of cell to create.

Now because the cell is an abstract from the real implementation it does not know / does not need to know of what type it is. For writing / modifying the cell I solve this problem by calling .write(ICellWriter) on the cell I want to persist. As the cell itself knows what type of data it contains, it knows which method of ICellWriter it needs to call (static polymorpism).

My problem:

Writing to the xlsx file is no problem. My problem is, how do I get the data out of my cell into my DTO/PONO without resorting to type checking -> If TypeOf variable is ClassX then doesomething End If. As Methods / Properties have to have different Signatures and differentiating by only using a different return type is not allowed.

Edit:

The holder (collection, in this case a row of a table/spreadsheet) of the objects (refering to the cells) does not know the concrete implementations. So for writing a cell I pass it a Cellwriter. This Cellwriter has overloaded methods like Write(num as Integer), Write(text as String), Write(datum as Date). The cell object that gets this passed to it then calls the Write() method with the data type it 开发者_如何学JAVAholds. This works, as no return value is passed back.

But what do I do when I need the concrete data type returned?

Any ideas, advice, insight?

Thanks

Edit:

Glossary:

  • DTO: Data Transfere Object
  • PONO: Plain Old .Net Object
  • xlsx: referring to file ending of excel workbook files

Edit:

The Cell "subtypes" implement a common interface and do not inherit from a common superclass.

Edit:

After some thinking about the problem I came to realize that it’s not possible without reflection or knowledge of what type of cell I am expecting. Basically I was trying to recreate a spreadsheet or something with similar functionality and way too abstract/configurable for my needs. Thanks for your time & effort put in to writing the answer. I accepted the answer that was closest to what I realized.


I don't think you can.

If I'm understanding correctly, you have a different types of cells (StringCell, IntCell) and each of those concrete classes returns an object of type 'Object'. When you are using the base class 'Cell' and getting it's value - it's of type Object.

To work with it as a String, or Integer, Or Date, etc...etc... I think you need to inspect the type of that object, one way or another. You can use TypeOf like you demonstrated; I've also seen things like '.GetValueAsString()/.GetValueAsInteger()' on the base class. But you still need knowledge enough to say 'Dim myInt as Integer = myCell.GetValueAsInteger()'

Generally speaking, at least if you subscribe to the SOLID principals, you shouldn't care.

It states that, in a computer program if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substitutes for objects of type T), without altering any of the desirable properties of that program (correctness, task performed, etc.)

http://en.wikipedia.org/wiki/Liskov_substitution_principle

If you have subtypes of cells, but you can't use them interchangeably, it's a good candidate for not using inheritance.

I don't know what you intending to do with the values in the cells that would require you to have the concrete class instead of using the base; but it might be possible to expose that functionality in the base itself. IE - if you need to add two cells, you can accomplish that treating them as generic cells (perhaps. At least provided they are of compatible types) without knowing what subtype they are. You should be able to return the base class in your DTO, regardless.

At least, I that's my understanding. I'd certainly wait for more people to chime in before listening to me.

0

精彩评论

暂无评论...
验证码 换一张
取 消