Collection of Generic Objects

  • Thread starter Thread starter msnews.microsoft.com
  • Start date Start date
M

msnews.microsoft.com

I got (what I hope to be is) a simple question....

I have a class called PropertyObject<T>

so in my code I created something like this..

name = new PropertyObject<string>("goot");
age = new PropertyObject<int>(20);

but what I would rather do is this

List<PropertyObject<T>> props = new List<PropertyObject>();
props.Add(new PropertyObject<string>("goot"));
props.Add(new PropertyObject<int>(20));

where the List<> props can only contain PropertyObject<T>'s of any T

Is this posible or does List<> have to contain only PropertyObjects of the
same generic type parameter and in which case I have to use an ArrayList?
 
A Generic class is only un-typed until you use it. It is the .Net equivalent
of a C++ Template, which can be used to create a variety of strongly-typed
classes having similar characteristics and/or behavior. Once you create an
instance of the class, you must pass a type parameter to it. At compile-time
it is strongly-typed. A Generic class, therefore is not like a base class,
or an Object, or a Variant. It cannot be used without passing a type
parameter to it. And once that type parameter is passed, it is set in stone.
For example, if you create a new PropertyObject<string>, how do you convert
it to a PropertyObject<int>? You don't. You can't.

In other words, what you're describing is not possible.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
If you push something hard enough,
it will fall over.
- Fudd's First Law of Opposition
 
In other words, what you're describing is not possible.

that's right.

however if you just look for a collection and are not aware of your options,
you could use:
System.Collection.ArrayList
or
 
Thanks Kevin,
Something in my head told me to think I could that because after all
they are all PropertyObjects...

Being new to something sometimes makes you reach for things that aren't
really there :)

-Scott
 
I understand perfectly Scott. Generics took me awhile to get my head around
as well. I just spent a long time doing it until it all gelled.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a horse to water,
but you can't make him think.
 
As Kevin states, you cannot do it directly, however you may be able do it
indirectly.

Have PropertyObject<T> inherit from a base class. Then use this base class
in List<T>.

Something like:

abstract class PropertyObject
{
// common behavior for a property object
}

class PropertyObject<T> : PropertyObject
{
// T specific behavior for a property object
}

List<PropertyObject> props = new List<PropertyObject>();
props.Add(new PropertyObject<string>("goot"));
props.Add(new PropertyObject<int>(20));

PropertyObject would contain all the common behavior that you expect to use
polymorphically via the List<T>, while PropertyObject<T> would contain all
the T specific behavior for a property.

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


|I got (what I hope to be is) a simple question....
|
| I have a class called PropertyObject<T>
|
| so in my code I created something like this..
|
| name = new PropertyObject<string>("goot");
| age = new PropertyObject<int>(20);
|
| but what I would rather do is this
|
| List<PropertyObject<T>> props = new List<PropertyObject>();
| props.Add(new PropertyObject<string>("goot"));
| props.Add(new PropertyObject<int>(20));
|
| where the List<> props can only contain PropertyObject<T>'s of any T
|
| Is this posible or does List<> have to contain only PropertyObjects of the
| same generic type parameter and in which case I have to use an ArrayList?
|
|
 
Nice idea, Jay. It is important to note, however, that Reflection would
still need to be used to discover the type of the particular version of
"PropertyObject" that would be in the list. Or, assuming that the base class
contained all the characteristics necessary to work with the objects while
in the List, Reflection could be termporarily unnecessary, at least until
the typed members of the objects in the List were used. In other words,
nothing would really be gained by using Generics here. A simple base class
and a number of derived classes would work just as well, since the Generic
List object would not contain any type information about what is stored in
it, other than the base type.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but you can't make it stink.
 
Kevin,
| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list.
If by Reflection you mean Object.GetType or "is" or "as", then I agree, you
need use Reflection to know the specific type of object in the list. As you
state normally with polymorphic code you don't need to know the specific
type of an object in the list. I hope you would agree that would defeat the
purpose of having polymorphic code.

| In other words,
| nothing would really be gained by using Generics here.
The "Gain" of Generics here is you don't have to explicitly declare
StringPropertyObject, IntPropertyObject, DoublePropertyObject, etc... They
are implicitly declared via the generic type PropertyObject<T>. In fact I
would hope for any T, you now have a specific PropertyObject (bearing in
mind any constraints that T might have). Of course if you need a truely
specialized version of PropertyObject you could define that in addition to
PropertyObject<T>.

One could define normal virtual methods on PropertyObject so I could use the
items in List<PropertyObject> polymophically, just as I would in .NET 1.0 or
1.1. This may however mean that PropertyObject has an object version of a
method/property, where PropertyObject<T> has a T version of the
method/property. Something like:

abstract class PropertyObject
{
// common behavior for a property object

public abstract object Value { get; set; }
}

class PropertyObject<T> : PropertyObject
{
// T specific behavior for a property object

private T m_value;

public PropertyObject(T value)
{
m_value = value;
}

public T TypedValue
{
get { return m_value; }
set { m_value = value; }
}

public override object Value
{
get { return TypedValue; }
set { TypedValue = (T)value; }
}
}

Of course the above could also be done with interfaces rather then a base
class, with an interface you can at least use explicit interface
implementation to avoid have both TypeValue & Value on PropertyObject<T>.

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list. Or, assuming that the base
class
| contained all the characteristics necessary to work with the objects while
| in the List, Reflection could be termporarily unnecessary, at least until
| the typed members of the objects in the List were used. In other words,
| nothing would really be gained by using Generics here. A simple base class
| and a number of derived classes would work just as well, since the Generic
| List object would not contain any type information about what is stored in
| it, other than the base type.
|
| --
| HTH,
|
| Kevin Spencer
| Microsoft MVP
| .Net Developer
| You can lead a fish to a bicycle,
| but you can't make it stink.
|
| message | > As Kevin states, you cannot do it directly, however you may be able do
it
| > indirectly.
| >
| > Have PropertyObject<T> inherit from a base class. Then use this base
class
| > in List<T>.
| >
| > Something like:
| >
| > abstract class PropertyObject
| > {
| > // common behavior for a property object
| > }
| >
| > class PropertyObject<T> : PropertyObject
| > {
| > // T specific behavior for a property object
| > }
| >
| > List<PropertyObject> props = new List<PropertyObject>();
| > props.Add(new PropertyObject<string>("goot"));
| > props.Add(new PropertyObject<int>(20));
| >
| > PropertyObject would contain all the common behavior that you expect to
| > use
| > polymorphically via the List<T>, while PropertyObject<T> would contain
all
| > the T specific behavior for a property.
| >
| > --
| > Hope this helps
| > Jay [MVP - Outlook]
| > .NET Application Architect, Enthusiast, & Evangelist
| > T.S. Bradley - http://www.tsbradley.net
| >
| >
| > | > |I got (what I hope to be is) a simple question....
| > |
| > | I have a class called PropertyObject<T>
| > |
| > | so in my code I created something like this..
| > |
| > | name = new PropertyObject<string>("goot");
| > | age = new PropertyObject<int>(20);
| > |
| > | but what I would rather do is this
| > |
| > | List<PropertyObject<T>> props = new List<PropertyObject>();
| > | props.Add(new PropertyObject<string>("goot"));
| > | props.Add(new PropertyObject<int>(20));
| > |
| > | where the List<> props can only contain PropertyObject<T>'s of any T
| > |
| > | Is this posible or does List<> have to contain only PropertyObjects of
| > the
| > | same generic type parameter and in which case I have to use an
| > ArrayList?
| > |
| > |
| >
| >
|
|
 
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.

Jay B. Harlow said:
Kevin,
| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list.
If by Reflection you mean Object.GetType or "is" or "as", then I agree,
you
need use Reflection to know the specific type of object in the list. As
you
state normally with polymorphic code you don't need to know the specific
type of an object in the list. I hope you would agree that would defeat
the
purpose of having polymorphic code.

| In other words,
| nothing would really be gained by using Generics here.
The "Gain" of Generics here is you don't have to explicitly declare
StringPropertyObject, IntPropertyObject, DoublePropertyObject, etc... They
are implicitly declared via the generic type PropertyObject<T>. In fact I
would hope for any T, you now have a specific PropertyObject (bearing in
mind any constraints that T might have). Of course if you need a truely
specialized version of PropertyObject you could define that in addition to
PropertyObject<T>.

One could define normal virtual methods on PropertyObject so I could use
the
items in List<PropertyObject> polymophically, just as I would in .NET 1.0
or
1.1. This may however mean that PropertyObject has an object version of a
method/property, where PropertyObject<T> has a T version of the
method/property. Something like:

abstract class PropertyObject
{
// common behavior for a property object

public abstract object Value { get; set; }
}

class PropertyObject<T> : PropertyObject
{
// T specific behavior for a property object

private T m_value;

public PropertyObject(T value)
{
m_value = value;
}

public T TypedValue
{
get { return m_value; }
set { m_value = value; }
}

public override object Value
{
get { return TypedValue; }
set { TypedValue = (T)value; }
}
}

Of course the above could also be done with interfaces rather then a base
class, with an interface you can at least use explicit interface
implementation to avoid have both TypeValue & Value on PropertyObject<T>.

--
Hope this helps
Jay [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list. Or, assuming that the base
class
| contained all the characteristics necessary to work with the objects
while
| in the List, Reflection could be termporarily unnecessary, at least
until
| the typed members of the objects in the List were used. In other words,
| nothing would really be gained by using Generics here. A simple base
class
| and a number of derived classes would work just as well, since the
Generic
| List object would not contain any type information about what is stored
in
| it, other than the base type.
|
| --
| HTH,
|
| Kevin Spencer
| Microsoft MVP
| .Net Developer
| You can lead a fish to a bicycle,
| but you can't make it stink.
|
| message | > As Kevin states, you cannot do it directly, however you may be able do
it
| > indirectly.
| >
| > Have PropertyObject<T> inherit from a base class. Then use this base
class
| > in List<T>.
| >
| > Something like:
| >
| > abstract class PropertyObject
| > {
| > // common behavior for a property object
| > }
| >
| > class PropertyObject<T> : PropertyObject
| > {
| > // T specific behavior for a property object
| > }
| >
| > List<PropertyObject> props = new List<PropertyObject>();
| > props.Add(new PropertyObject<string>("goot"));
| > props.Add(new PropertyObject<int>(20));
| >
| > PropertyObject would contain all the common behavior that you expect
to
| > use
| > polymorphically via the List<T>, while PropertyObject<T> would contain
all
| > the T specific behavior for a property.
| >
| > --
| > Hope this helps
| > Jay [MVP - Outlook]
| > .NET Application Architect, Enthusiast, & Evangelist
| > T.S. Bradley - http://www.tsbradley.net
| >
| >
| > | > |I got (what I hope to be is) a simple question....
| > |
| > | I have a class called PropertyObject<T>
| > |
| > | so in my code I created something like this..
| > |
| > | name = new PropertyObject<string>("goot");
| > | age = new PropertyObject<int>(20);
| > |
| > | but what I would rather do is this
| > |
| > | List<PropertyObject<T>> props = new List<PropertyObject>();
| > | props.Add(new PropertyObject<string>("goot"));
| > | props.Add(new PropertyObject<int>(20));
| > |
| > | where the List<> props can only contain PropertyObject<T>'s of any
T
| > |
| > | Is this posible or does List<> have to contain only PropertyObjects
of
| > the
| > | same generic type parameter and in which case I have to use an
| > ArrayList?
| > |
| > |
| >
| >
|
|
 
Thanks for all your suggestions, I ended up making a keyed collection of the
PropertyObjects
below is the what I doing... this is just a learning exercise. the User
class (at the bottom) is the resultant use of the mess above it :).
I have no idea if this is good practice but it was be interesting to play
with.

class NameObjectCollectionBase: PropertyObjectCollection {
public T GetValue<T>(string name) {}
public void SetValue<T>(string name, T value){}
public PropertyObject<T> GetProperty<T>(string name);
public PropertyObject<T> Add<T>(string name, T value){}

public void Undo() {
foreach(object o in InnerList)
((IUndo)o).Undo());

return success;
}
public void Redo(){
foreach(object o in InnerList)
((IRedo)o).Redo());

return success;
}
}

class abstract ComponentBase : IUndo, IRedo {
protected virtual PropertyObjectCollection Properties {get;}

public ObjectStatus Status {get;} //changed, unchanged, new, deleted...
etc.

public virtual void Undo(){
Properties.Undo();
}
public virtual void Redo(){
Properties.Redo();
}

public abstract void Save();
}

class User : ComponentBase, ILoad {
public int ID {
get{return Properties.GetValue<int>("ID", -1);}
}
public string Name {
get{return Properties.GetValue<string>("Name");}
set{Properties.SetValue<String>("Name", value);}
}

public int Age {
get{return Properties.GetValue<int>("Age");}
set{Properties.SetValue<int>("Age", value);}
}

public override void Save() {
DataProvider.Instance().SaveUser(Properties);
}

void ILoad.Load() {
DataProvider.Instance().LoadUser(Properties);
}
}

Kevin Spencer said:
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.

Jay B. Harlow said:
Kevin,
| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list.
If by Reflection you mean Object.GetType or "is" or "as", then I agree,
you
need use Reflection to know the specific type of object in the list. As
you
state normally with polymorphic code you don't need to know the specific
type of an object in the list. I hope you would agree that would defeat
the
purpose of having polymorphic code.

| In other words,
| nothing would really be gained by using Generics here.
The "Gain" of Generics here is you don't have to explicitly declare
StringPropertyObject, IntPropertyObject, DoublePropertyObject, etc...
They
are implicitly declared via the generic type PropertyObject<T>. In fact I
would hope for any T, you now have a specific PropertyObject (bearing in
mind any constraints that T might have). Of course if you need a truely
specialized version of PropertyObject you could define that in addition
to
PropertyObject<T>.

One could define normal virtual methods on PropertyObject so I could use
the
items in List<PropertyObject> polymophically, just as I would in .NET 1.0
or
1.1. This may however mean that PropertyObject has an object version of a
method/property, where PropertyObject<T> has a T version of the
method/property. Something like:

abstract class PropertyObject
{
// common behavior for a property object

public abstract object Value { get; set; }
}

class PropertyObject<T> : PropertyObject
{
// T specific behavior for a property object

private T m_value;

public PropertyObject(T value)
{
m_value = value;
}

public T TypedValue
{
get { return m_value; }
set { m_value = value; }
}

public override object Value
{
get { return TypedValue; }
set { TypedValue = (T)value; }
}
}

Of course the above could also be done with interfaces rather then a base
class, with an interface you can at least use explicit interface
implementation to avoid have both TypeValue & Value on PropertyObject<T>.

--
Hope this helps
Jay [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Nice idea, Jay. It is important to note, however, that Reflection would
| still need to be used to discover the type of the particular version of
| "PropertyObject" that would be in the list. Or, assuming that the base
class
| contained all the characteristics necessary to work with the objects
while
| in the List, Reflection could be termporarily unnecessary, at least
until
| the typed members of the objects in the List were used. In other words,
| nothing would really be gained by using Generics here. A simple base
class
| and a number of derived classes would work just as well, since the
Generic
| List object would not contain any type information about what is stored
in
| it, other than the base type.
|
| --
| HTH,
|
| Kevin Spencer
| Microsoft MVP
| .Net Developer
| You can lead a fish to a bicycle,
| but you can't make it stink.
|
| message | > As Kevin states, you cannot do it directly, however you may be able
do
it
| > indirectly.
| >
| > Have PropertyObject<T> inherit from a base class. Then use this base
class
| > in List<T>.
| >
| > Something like:
| >
| > abstract class PropertyObject
| > {
| > // common behavior for a property object
| > }
| >
| > class PropertyObject<T> : PropertyObject
| > {
| > // T specific behavior for a property object
| > }
| >
| > List<PropertyObject> props = new List<PropertyObject>();
| > props.Add(new PropertyObject<string>("goot"));
| > props.Add(new PropertyObject<int>(20));
| >
| > PropertyObject would contain all the common behavior that you expect
to
| > use
| > polymorphically via the List<T>, while PropertyObject<T> would
contain
all
| > the T specific behavior for a property.
| >
| > --
| > Hope this helps
| > Jay [MVP - Outlook]
| > .NET Application Architect, Enthusiast, & Evangelist
| > T.S. Bradley - http://www.tsbradley.net
| >
| >
| > | > |I got (what I hope to be is) a simple question....
| > |
| > | I have a class called PropertyObject<T>
| > |
| > | so in my code I created something like this..
| > |
| > | name = new PropertyObject<string>("goot");
| > | age = new PropertyObject<int>(20);
| > |
| > | but what I would rather do is this
| > |
| > | List<PropertyObject<T>> props = new List<PropertyObject>();
| > | props.Add(new PropertyObject<string>("goot"));
| > | props.Add(new PropertyObject<int>(20));
| > |
| > | where the List<> props can only contain PropertyObject<T>'s of any
T
| > |
| > | Is this posible or does List<> have to contain only PropertyObjects
of
| > the
| > | same generic type parameter and in which case I have to use an
| > ArrayList?
| > |
| > |
| >
| >
|
|
 
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>>
 
Scott,
Have you considered something like (based on my earlier example):

class PropertyObjectCollection :
System.Collections.ObjectModel.KeyedCollection<String, PropertyObject>
{
public T GetValue<T>(string name)
{
return GetProperty<T>(name).TypedValue;
}

public void SetValue<T>(string name, T value)
{
GetProperty<T>(name).TypedValue = value;
}

public PropertyObject<T> GetProperty<T>(string name)
{
return (PropertyObject<T>)this[name];
}

public PropertyObject<T> Add<T>(string name, T value)
{
PropertyObject<T> item = new PropertyObject<T>(value);
Add(item);
return item;
}

protected override string GetKeyForItem(PropertyObject item)
{
return item.Key;
}
}

Of course the danger of the above code is that objects that are not
PropertyObject<T> could be placed in the collection...


FWIW: Your GetProperty<T> and GetValue<T> "violates" a FxCop rule as its
"ambiguous".

Here is a thread that discusses it:

http://groups.google.com/group/micr...bb32de857b1/cf4e46ca8f99b798#cf4e46ca8f99b798

I can see using them in the above case, as they "encapsulate a downcast",
however I'm not sure how often I would use them.

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Thanks for all your suggestions, I ended up making a keyed collection of
the
| PropertyObjects
| below is the what I doing... this is just a learning exercise. the User
| class (at the bottom) is the resultant use of the mess above it :).
| I have no idea if this is good practice but it was be interesting to play
| with.
|
| class NameObjectCollectionBase: PropertyObjectCollection {
| public T GetValue<T>(string name) {}
| public void SetValue<T>(string name, T value){}
| public PropertyObject<T> GetProperty<T>(string name);
| public PropertyObject<T> Add<T>(string name, T value){}
|
| public void Undo() {
| foreach(object o in InnerList)
| ((IUndo)o).Undo());
|
| return success;
| }
| public void Redo(){
| foreach(object o in InnerList)
| ((IRedo)o).Redo());
|
| return success;
| }
| }
|
| class abstract ComponentBase : IUndo, IRedo {
| protected virtual PropertyObjectCollection Properties {get;}
|
| public ObjectStatus Status {get;} //changed, unchanged, new, deleted...
| etc.
|
| public virtual void Undo(){
| Properties.Undo();
| }
| public virtual void Redo(){
| Properties.Redo();
| }
|
| public abstract void Save();
| }
|
| class User : ComponentBase, ILoad {
| public int ID {
| get{return Properties.GetValue<int>("ID", -1);}
| }
| public string Name {
| get{return Properties.GetValue<string>("Name");}
| set{Properties.SetValue<String>("Name", value);}
| }
|
| public int Age {
| get{return Properties.GetValue<int>("Age");}
| set{Properties.SetValue<int>("Age", value);}
| }
|
| public override void Save() {
| DataProvider.Instance().SaveUser(Properties);
| }
|
| void ILoad.Load() {
| DataProvider.Instance().LoadUser(Properties);
| }
| }
|
<<snip>>
 
Doh!

The below code requires a "Key" to be added to PropertyObject

abstract class PropertyObject
{
private string m_name;

public string Name
{
get { return m_name; }
set { m_name = value; }
}


| class PropertyObjectCollection :
| System.Collections.ObjectModel.KeyedCollection<String, PropertyObject>
...
| protected override string GetKeyForItem(PropertyObject item)
| {
| return item.Name;
| }


I had called it Key, but thinking about it its really Name, of course it
probably should have been read only... ;-)

--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


message | Scott,
| Have you considered something like (based on my earlier example):
|
| class PropertyObjectCollection :
| System.Collections.ObjectModel.KeyedCollection<String, PropertyObject>
| {
| public T GetValue<T>(string name)
| {
| return GetProperty<T>(name).TypedValue;
| }
|
| public void SetValue<T>(string name, T value)
| {
| GetProperty<T>(name).TypedValue = value;
| }
|
| public PropertyObject<T> GetProperty<T>(string name)
| {
| return (PropertyObject<T>)this[name];
| }
|
| public PropertyObject<T> Add<T>(string name, T value)
| {
| PropertyObject<T> item = new PropertyObject<T>(value);
| Add(item);
| return item;
| }
|
| protected override string GetKeyForItem(PropertyObject item)
| {
| return item.Key;
| }
| }
|
| Of course the danger of the above code is that objects that are not
| PropertyObject<T> could be placed in the collection...
|
|
| FWIW: Your GetProperty<T> and GetValue<T> "violates" a FxCop rule as its
| "ambiguous".
|
| Here is a thread that discusses it:
|
|
http://groups.google.com/group/micr...bb32de857b1/cf4e46ca8f99b798#cf4e46ca8f99b798
|
| I can see using them in the above case, as they "encapsulate a downcast",
| however I'm not sure how often I would use them.
|
| --
| Hope this helps
| Jay [MVP - Outlook]
| .NET Application Architect, Enthusiast, & Evangelist
| T.S. Bradley - http://www.tsbradley.net
|
|
| || Thanks for all your suggestions, I ended up making a keyed collection of
| the
|| PropertyObjects
|| below is the what I doing... this is just a learning exercise. the User
|| class (at the bottom) is the resultant use of the mess above it :).
|| I have no idea if this is good practice but it was be interesting to play
|| with.
||
|| class NameObjectCollectionBase: PropertyObjectCollection {
|| public T GetValue<T>(string name) {}
|| public void SetValue<T>(string name, T value){}
|| public PropertyObject<T> GetProperty<T>(string name);
|| public PropertyObject<T> Add<T>(string name, T value){}
||
|| public void Undo() {
|| foreach(object o in InnerList)
|| ((IUndo)o).Undo());
||
|| return success;
|| }
|| public void Redo(){
|| foreach(object o in InnerList)
|| ((IRedo)o).Redo());
||
|| return success;
|| }
|| }
||
|| class abstract ComponentBase : IUndo, IRedo {
|| protected virtual PropertyObjectCollection Properties {get;}
||
|| public ObjectStatus Status {get;} //changed, unchanged, new,
deleted...
|| etc.
||
|| public virtual void Undo(){
|| Properties.Undo();
|| }
|| public virtual void Redo(){
|| Properties.Redo();
|| }
||
|| public abstract void Save();
|| }
||
|| class User : ComponentBase, ILoad {
|| public int ID {
|| get{return Properties.GetValue<int>("ID", -1);}
|| }
|| public string Name {
|| get{return Properties.GetValue<string>("Name");}
|| set{Properties.SetValue<String>("Name", value);}
|| }
||
|| public int Age {
|| get{return Properties.GetValue<int>("Age");}
|| set{Properties.SetValue<int>("Age", value);}
|| }
||
|| public override void Save() {
|| DataProvider.Instance().SaveUser(Properties);
|| }
||
|| void ILoad.Load() {
|| DataProvider.Instance().LoadUser(Properties);
|| }
|| }
||
| <<snip>>
|
|
 
| 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 said:
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>>
 
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>>
| >
| >
|
|
 
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 said:
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>>
| >
| >
|
|
 
Back
Top