How to parse various types without a switch?

  • Thread starter Thread starter Guest
  • Start date Start date
Thank you for your answer.

I guess this discussion drifted a bit off topic.
I am well aware of patterns and was using them in various languages
(when appropriate)
but this question was about the .NET library (framework).

Patterns will not save me from calling the framework Parse() or
Convert.ChangeType() routines. They will just pile up more code on top.

Note that you can do this with the visitor pattern as well. You chose the
observer pattern.

I don't believe I am using any pattern right now, especially an observer.
As you, probably aware, the essence of an observer pattern is that
one or several listeners are registered to hear an event which
may be raised by the observed object. My code certainly does not
have any listeners, events or observed objects. All it has is a static
table of structures describing types (with names and delegates for
parsing),
several one-or-two-line wrappers for Parse routines for various types,
an array of types for a particular CSV, and a simple loop,
which invokes an appropriate delegate for each field of CSV row.
So, if you insist on using OO terms here, I have a trivial case of
polymorphism and no more than that.
I would agree that there are more classes. I would also state that you
have a much more OO approach this way.

I am not a purist, who is using a particular approach just for the sake of
using it.
OO approach is not a sacred cow and using it is not the goal of my project.
The code should be simple, reliable and efficient. If OO helps me to
achieve it, great, if not - forget it.
I would disagree that it looks more complex. On the contrary, it looks
much simpler.

Your code (writing a dozen or two of custom decorator classes for system
types),
will not fit a screen. My table-driven approach does fit one screen and have
less executable code (only one-line wrappers) and a loop. So, it is simpler,
easier to read, maintain and debug. Code bloat will achieve the opposite
- more code, harder to read, maintain, have more bugs, etc.

By the way, I posted in another response a thought that C++ may have allowed
me to generate custom decorators for system types using templates.
In that case I may have considered using the decorator approach
if generation of a single decorator will take only one line
MyDecorator<double> said:
I pointed this out to let you know that, unlike other suggestions, this
pattern does not require reflection.

Sure, I never said that it does. Patterns usually use virtual methods,
which (I guess) should be similar to delegates in performance.
So, I don't reject your method because of performance, but because
of code bloat.


Thank you
John
 
Actually I found that I can create templates using managed C++:

interface class MyParserIntf
{
public:
virtual Object^ Parse(String^ str);
};

template <typename T>
ref class MyParser : public MyParserIntf
{
public:
virtual Object^ Parse(String^ str)
{
return T::Parse(str);
}
};
.......
array<MyParserIntf^> ^ Parsers = gcnew array<MyParserIntf^>
{//All types known to the CSV processor
gcnew MyParser<Int32>(),
gcnew MyParser<DateTime>(),
gcnew MyParser<double>(),
..........
};
......
array<MyParserIntf^> ^ CurCSVParsers;
generate CurCSVParsers array of parsers for the current CSV
.......
for(int i = 0; i < CurCSVParsers->Length; i++)
{
l_Results = CurCSVParsers->Parse(l_SampleRow);
}


This way I can implement the decorator pattern as Nick suggested
with only a single line per the system type
(if I will find any any advantage of doing so over the simple code above).

But I don't see a way to mix the C++ and C# in the same project.
And creating a separate DLL just for parsing seems to be an overkill.

John
 
John,
While reviewing another thread, I found Java 5.0 supports very powerful
Enums.

http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

From what I've read Java 5.0 got Enums right! At least they implemented
Enums the way I probably would have, then added some features that are
useful, but I'm not sure I would have included...

I could see you defining your Field type as a Java Enum instead of using
System.Type, allowing you to give each enum constant its own unique
behavior...

Although it doesn't help you on this project, I found it to be a very cool
feature...

Just a thought
Jay

<John> wrote in message | Actually I found that I can create templates using managed C++:
|
| interface class MyParserIntf
| {
| public:
| virtual Object^ Parse(String^ str);
| };
|
| template <typename T>
| ref class MyParser : public MyParserIntf
| {
| public:
| virtual Object^ Parse(String^ str)
| {
| return T::Parse(str);
| }
| };
| ......
| array<MyParserIntf^> ^ Parsers = gcnew array<MyParserIntf^>
| {//All types known to the CSV processor
| gcnew MyParser<Int32>(),
| gcnew MyParser<DateTime>(),
| gcnew MyParser<double>(),
| ..........
| };
| .....
| array<MyParserIntf^> ^ CurCSVParsers;
| generate CurCSVParsers array of parsers for the current CSV
| ......
| for(int i = 0; i < CurCSVParsers->Length; i++)
| {
| l_Results = CurCSVParsers->Parse(l_SampleRow);
| }
|
|
| This way I can implement the decorator pattern as Nick suggested
| with only a single line per the system type
| (if I will find any any advantage of doing so over the simple code above).
|
| But I don't see a way to mix the C++ and C# in the same project.
| And creating a separate DLL just for parsing seems to be an overkill.
|
| John
|
|
|
|
 
While reviewing another thread, I found Java 5.0 supports very powerful

Yes, kind of overblown enums.
Although it doesn't help you on this project, I found it to be a very cool
feature...

Well, you are wrong. Reading about Java Enums, which now allow
so called "constant-specific methods",
I realized that these are pretty similar to old and familiar anonymous
classes,
which made me thinking that C# 2.0 also have similar anonymous methods,
so I can throw away those separate Parse wrappers and implement the parsers
inline
right in the table:

delegate object Parse(string str);
static Parse[] Types = new Parse[] {
delegate(string str) {return Int32.Parse(str);},
delegate(string str) {return DateTime.Parse(str);},
delegate(string str) {return double.Parse(str);},
};
.....
for (int i = 0; i < l_SampleRow.Length; i++)
{
l_Results = (CSVTypes)(l_SampleRow);
}
Looks simple enough.

Thank you
John
 
John,
| which made me thinking that C# 2.0 also have similar anonymous methods,
| so I can throw away those separate Parse wrappers and implement the
parsers
| inline
| right in the table:
If you have the luxury of using C# 2.0, then yes anonymous methods might be
a good way to simplify the wrappers methods.

It appears that it should work, does it?

Thanks for the follow up.
Jay

<John> wrote in message |> While reviewing another thread, I found Java 5.0 supports very powerful
| > Enums.
| >
| > http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
|
| Yes, kind of overblown enums.
|
| > Although it doesn't help you on this project, I found it to be a very
cool
| > feature...
|
| Well, you are wrong. Reading about Java Enums, which now allow
| so called "constant-specific methods",
| I realized that these are pretty similar to old and familiar anonymous
| classes,
| which made me thinking that C# 2.0 also have similar anonymous methods,
| so I can throw away those separate Parse wrappers and implement the
parsers
| inline
| right in the table:
|
| delegate object Parse(string str);
| static Parse[] Types = new Parse[] {
| delegate(string str) {return Int32.Parse(str);},
| delegate(string str) {return DateTime.Parse(str);},
| delegate(string str) {return double.Parse(str);},
| };
| ....
| for (int i = 0; i < l_SampleRow.Length; i++)
| {
| l_Results = (CSVTypes)(l_SampleRow);
| }
| Looks simple enough.
|
| Thank you
| John
|
|
 
Back
Top