Kevin,
| Well, that brings me back to my earlier message, in which I mentioned
that
| if all the client has to do is work with the Base type, it might be
useful
| in some way. I will elaborate on this below.
Which was my point from the beginning, not sure where we missed what each
other was saying.
| You might want to read up on polymorphism. Here's a good starting point:
Please, don't insult my intelligence! :-|
I hope you don't think I was attempting to insult yours!
I normally use the following to define Polymorphism:
http://www.javaworld.com/javaworld/jw-04-2001/jw-0413-polymorph.html
However I will include your link with the above link.
FYI: I was emphasizing Polymorphism, as you kept wanting to talk about
Reflection, which IMHO too many developers start using when there are
"better" methods available.
--
Hope this helps
Jay [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley -
http://www.tsbradley.net
|> | In the first case, how does the
| > | client know the type without using Reflection?
| > As in any polymorphic case, the client doesn't (shouldn't) care what
the
| > type is, other then its one of the base types! Polymorphic code
operates
| > (should operate!) on the base type not the specific derived types.
|
| Well, that brings me back to my earlier message, in which I mentioned
that
| if all the client has to do is work with the Base type, it might be
useful
| in some way. I will elaborate on this below.
|
| > Again, polymorphism suggests, that the client doesn't (shouldn't) care
| > what
| > the type is other then some known base type.
|
| You might want to read up on polymorphism. Here's a good starting point:
|
|
http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
|
| Polymorphism, in and of itself, suggests nothing about the client. There
are
| certainly uses for objects whose types are not known at a certain point
| during program execution, and under certain circumstances. If the type
of
an
| object is not germaine to an operation (such as creating a list of
objects
| of various types), the type does not need to be known. But that is the
| limitation of its usefulness. Once the type of the data that is not
known
| needs to be known (for example, when using it), there must be some
mechanism
| for either discovering the type (reflection), coercion, or inference.
| Otherwise, the data type remains unknown, and the data is useless.
|
| Consider the Generic List of properties created in Scott's final
solution.
| The property objects are added to a Generic List, and that is certainly
| possible. However, note the Name of each Property, and how he uses the
Name
| in a set of strongly-typed properties, to identify the type. In essence,
the
| Property Name is a substitute for the type name. In order to work with
the
| actual values in the Generic list, the User Class must know the type
| associated with each Name, and can then work with the actual data in the
| Property object. Otherwise, not. Any class which did not have this
Name=Type
| association could not make any use of the data in these properties.
|
| For Scott's solution, in essence, he creates a Generic List that is
| unnecessary, as the Properties that are associated with the various
names
| pull the Properties out of the list by name and "cast" them as the type
that
| they are. While this might be a useful exercise in understanding
Generics,
| it has no real value, in that it requires both named (and typed)
properties,
| and a Generic List of the same properties, with the type information
| removed. In fact, I wouldn't consider it a very useful exercise in
| understanding Generics, as this is not how Generics are employed, and
for
| good reason. The Properties List is redundant. It is never used. The
| strongly-typed property definitions in the User class would suffice in
and
| of themselves.
|
| A Generic class is a Template for creating strongly-typed sub-classes
that
| have the same characteristics. The advantage of a Generic class over a
Base
| Type is that the Generic class enables the developer to create a wide
| variety of sub-types without having to separately define each sub-type
as
a
| class. An excellent example of this is the
| System.Collections.ObjectModel.Collection<T> class. Prior to the
inclusion
| of Generics in the .Net Framework, the System.Collections.CollectionBase
| class would be used to create strongly-typed collections, by using it as
a
| Base Class, and employing casting in the inherited classes (at run-time)
to
| achieve the strong typing. In the System.Collections.CollectionBase
class,
| all Collection members are of the base class System.Object. This usage
of
| casting at run-time incurs a certain amount of expense, and requires a
| separate, specific definition for each derived Collection type to be
defined
| explicitly somewhere.
|
| With System.Collections.ObjectModel.Collection<T>, in fact, the class
itself
| is useless without a type parameter. It is merely a Template for
creating
| classes. Once a type parameter is passed to an instance of the class, it
| *is* a Collection of that type of object. It cannot be any other type.
It
is
| compiled as that type. The sub-type is created "on the fly" at
compile-time,
| without requiring a separate definition of a derived type anywhere. And
no
| casting is required at run-time. A Collection of any type of object can
| therefore be defined and used for any class that needs one without
defining
| a derived class, or employing casting.
|
| This distinction is extremely important to understand in order to make
good
| use of Generics. .Net is a safely-typed programming technology, and one
must
| be careful to discriminate between, for example, the use of Base classes
and
| Generics, versus Variants. Variants employ a type of Reflection at
run-time
| to discover their underlying type, and they are expensive in more ways
than
| one. Base classes are more efficient in that they are strongly typed,
and
| the derived classes are strongly typed. However, unless the type of the
| derived class is known, only the Base class part is useful, as long as
the
| type of the Base class is known. Strong data typing is efficient,
type-safe,
| and superior in many ways to the use of variants. It is faster, and
prevents
| developer error by means of its strictness.
|
| --
| HTH,
|
| Kevin Spencer
| Microsoft MVP
| .Net Developer
| You can lead a fish to a bicycle,
| but you can't make it stink.
|
| message | > Kevin,
| > | In the first case, how does the
| > | client know the type without using Reflection?
| > As in any polymorphic case, the client doesn't (shouldn't) care what
the
| > type is, other then its one of the base types! Polymorphic code
operates
| > (should operate!) on the base type not the specific derived types.
| >
| >
| > | In the second case, while the
| > | client may be able to get the value, the type is still not known,
and
| > | Reflection is necessary to determine it.
| > Again, polymorphism suggests, that the client doesn't (shouldn't) care
| > what
| > the type is other then some known base type.
| >
| >
| > In Scott's case he knows that Properties["Name"] is going to be a
String
| > property, so he can simply cast the returned object to a String (or
| > PropertyObject<String> as the case may be). Which he does indirectly
via
| > his
| > GetValue<T> methods. Seeing as he is expecting a
PropertyObject<String>
to
| > come back, IMHO getting the InvalidCastException is acceptable, if he
| > didn't
| > get a PropertyObject<String> he was expecting.
| >
| > --
| > Hope this helps
| > Jay [MVP - Outlook]
| > .NET Application Architect, Enthusiast, & Evangelist
| > T.S. Bradley -
http://www.tsbradley.net
| >
| >
| > | > | Hi Jay,
| > |
| > | I don't see it. Either you use the typed version of the value, in
which
| > case
| > | you have to know the type, or you use the object version of the
value
in
| > | which case you still don't know the type. In the first case, how
does
| > the
| > | client know the type without using Reflection? In the second case,
while
| > the
| > | client may be able to get the value, the type is still not known,
and
| > | Reflection is necessary to determine it. So, I still don't see any
use
| > for
| > | Generics in this case. I could be wrong, though. Been quite busy
today.
| > |
| > | --
| > | HTH,
| > |
| > | Kevin Spencer
| > | Microsoft MVP
| > | .Net Developer
| > | You can lead a fish to a bicycle,
| > | but you can't make it stink.
| > |
| > <<snip>>
| >
| >
|
|