Re: Collection of Generic Objects

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hi Jay,

I didn't intend to insult your intelligence. However, the article you
mentioned is in full agreement with the Wikipedia article I mentioned, in
that it discriminates between the broad term "polymorphism" and specific
uses of the term "polymorphism" in different contexts. To quote the article
you referenced:

"Polymorphism is a broad object-oriented term. Though we usually equate the
general concept with the subtype variety, there are actually four different
kinds of polymorphism."

My point was simply that you cannot attribute a specific type of
polymorphism with the term "polymorphism," and be intellectually honest.
Again, the article you cited specifically details the same issues I
discussed in my previous message. In the auhor's discussion of various types
of polymorphism, he refers to the topic of Generics in his dicussion of
"parametric polymorphism," which "allows the use of a single abstraction
across many types." In the introduction to the article, he states
"Polymorphism in Java is invariably subtype polymorphism." This is not the
same as Generics, which was not supported at the time the article was
written (2001), but is supported in Java now (since 2003).

The difference between subtype polymorphism and parametric polymorphism lies
in the inherent limitation of subtype polymorphism, which is that the
allowable types must all be derived from a common base type (such as, in the
case of .Net, System.Collections.CollectionBase), and that this form of
polymorphism involves late-binding, in that derived classes must cast their
members at run-time to the appropriate subtype of the base class, or provide
an implementation for each specific type. This type of polymorphism requires
some form of coercion, overloading, overriding, and/or inclusion, to
*simulate* a transparency across multiple types. The transparency does not
(and can not, in fact) actually exist. The late-binding aspect of the
derived class provides it. Within each subtype, a separate implementation
exists for each specific type referrenced by the client.

Generics represent true parametric polymorphism. However, while this removes
the late-binding from the equation, making the classes strongly-typed at
compile-time, it also introduces a number of restrictions. Since you like to
read JavaWorld, you might like to take a look at the following article on
Generics, from June 2004:
http://www.javaworld.com/javaworld/jw-06-2004/jw-0607-tiger2.html. In this
article, the author points out the nature of these restrictions in a number
of illustrations which point up the fact that a Generic type is a single,
strongly-typed instance of a class. It cannot be coerced, overloaded, or
overridden. One cannot treat 2 different Generic types as though they were
of the same type.

Therefore, while one might be able to create a Generic List of a certain
Generic type, only the aspects of that Generic type which are not
type-specific could be used without knowing the type parameter passed to
each class instance in the List. In the case of the OP's hypothetical
situation, this means that different types could be added to and removed
from the List. Once a client application needs access to the type-specific
aspects of the instances, it must either know the type of the instance, or
must use Reflection to discover it. And as I pointed out in my previous
message, this makes the use of Generics in his case inappropriate. That is
not where the power and usefulness of Generics lies. His User class must
implement properties that use the Name property of the Property<T> instance
to derive the type of the instance. And this is only known because he has
implemented the User class code himself, and employs a naming convention
that is not enforced other than in the User class itself (not in the
Property<T> class). Any other class will not know the type of the
Property<T> object without using Reflection. And to create a Property<T>
having a name property that is not the exact name that signifies the type
would be tragic. Even the User class would not know what to do with it,
except by using Reflection. He has substituted a volatile Name property for
an immutable type. I'm sure you can agree that this defies logic. And the
more I think about it, the more I am convinced that his exercise in
understanding Generics is not a good one.

I would propose that if he wants to understand Generics, he should implement
a useful Generic class, one that employs Generics in the way which takes
true advantage of their power. Generics are indeed powerful, and I have made
good use of them on more than one occasion. In fact, I consider Generics to
be possibly the most powerful addition to the .Net platform 2.0.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but you can't make it stink.

"Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@xxxxxxxxxxxxx> wrote in
message news:OcxfhwE%23FHA.356@xxxxxxxxxxxxxxxxxxxxxxx
> 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
>
>
> "Kevin Spencer" <kevin@xxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
> news:e9xxI5D%23FHA.1332@xxxxxxxxxxxxxxxxxxxxxxx
> |> | 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.
> |
> | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@xxxxxxxxxxxxx> wrote in
> | message news:%23ec8jsC%23FHA.3928@xxxxxxxxxxxxxxxxxxxxxxx
> | > 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
>| >
> | >
> | > "Kevin Spencer" <kevin@xxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
> | > news:ubJwJv39FHA.1148@xxxxxxxxxxxxxxxxxxxxxxx
> | > | 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>>
> | >
> | >
> |
> |
>
>


.



Relevant Pages

  • Short Steps Toward Generic Programming: Introduction
    ... since I have promised to publicize the present crop of Fortran ... more detail) my proposal for generic programming. ... Another form of polymorphism that is simle in another way is called ... similar to the ad-hoc generics. ...
    (comp.lang.fortran)
  • Re: Design problem with inheritance
    ... When you need to vary types use generics or templates if your ... Generics provide polymorphism for poor. ... template class Derived1: ... I meant that if you have stack generic, then you cannot put different types ...
    (comp.object)
  • Re: Java type-casting -- Q3
    ... Are you saying that polymorphism is a problem to which generics is the solution in Java? ...
    (comp.lang.java.programmer)
  • Re: Design problem with inheritance
    ... When you need to vary types use generics or templates if your ... a static form of polymorphism. ... to have a container of polymorphic objects. ...
    (comp.object)
  • Re: Design problem with inheritance
    ... When you need to vary types use generics or templates if your ... a static form of polymorphism. ... template class Derived1: public Base ...
    (comp.object)