From: Anthony Paul on
Let's say that I would like a generic type that supports Min/Max
properties and can be double or integer or even datetime if need be,
something flexible.

So I go about creating the following generic interface :

*note : in reality I implement the IComparable and IEquatable generic
interfaces and associated overriden methods, but I've cut everything
down to the bare minimum for this example.

public interface IMinMax<T>
{
T Min{get;}
T Max{get;}
}

and the following generic struct :

public struct MinMax<T> : IMinMax<T>
{
private readonly T min;
private readonly T max;

public T Min
{
get
{
return min;
}
}

public T Max
{
get
{
return max;
}
}

public MinMax(T min, T max)
{
this.min = min;
this.max = max;
}

}


Now here's some code to use it :

IMinMax<int> intMinMax = new MinMax<int>(0, 100); // percentage range
IMinMax<d> dateMinMax = new MinMax<DateTime>(new DateTime(1973, 10,
4), DateTime.Now); // date range


Okay, so here's the problem... what if I have the following
procedure :

public void DoSomething(object o)
{
IMinMax<> mm = (IMinMax<>) o; // this doesn't work

// do something with mm.Min and mm.Max here
}

and I want to call the procedure as follows :

DoSomething(intMinMax);
DoSomething(dateMinMax);


How do we go about doing something with Min and Max? Obviously there's
a lot of meat missing in the code and I simplified it quite
unrealistically for the purpose of this newsgroup so please no
questions as to why I would want to do it... this comes up all the
time in one form or another.

I guess the real question is... once you've cast a generic interface
to an object, how do you go about extracting its information at run-
time? In my case I happen to know the type at runtime but the
following modified method still doesn't work :

public void DoSomething(Type t, object o)
{
IMinMax<t> mm = (IMinMax<t>) o; // still doesn't work

// do something with mm.Min and mm.Max here
}


Regards!

Anthony

From: Sheng Jiang[MVP] on
Your struct (or value type) is boxed and the type information seems lost
when it is converted to object..
You can try C++/CLI, which retains type information when you box a value
type.
Reference
C++: The Most Powerful Language for .NET Framework Programming by Kenny
Kerr, MSDN
--
Sheng Jiang
Microsoft MVP in VC++
"Anthony Paul" <anthonypaulo(a)gmail.com> wrote in message
news:1184707400.744962.124550(a)o11g2000prd.googlegroups.com...
> Let's say that I would like a generic type that supports Min/Max
> properties and can be double or integer or even datetime if need be,
> something flexible.
>
> So I go about creating the following generic interface :
>
> *note : in reality I implement the IComparable and IEquatable generic
> interfaces and associated overriden methods, but I've cut everything
> down to the bare minimum for this example.
>
> public interface IMinMax<T>
> {
> T Min{get;}
> T Max{get;}
> }
>
> and the following generic struct :
>
> public struct MinMax<T> : IMinMax<T>
> {
> private readonly T min;
> private readonly T max;
>
> public T Min
> {
> get
> {
> return min;
> }
> }
>
> public T Max
> {
> get
> {
> return max;
> }
> }
>
> public MinMax(T min, T max)
> {
> this.min = min;
> this.max = max;
> }
>
> }
>
>
> Now here's some code to use it :
>
> IMinMax<int> intMinMax = new MinMax<int>(0, 100); // percentage range
> IMinMax<d> dateMinMax = new MinMax<DateTime>(new DateTime(1973, 10,
> 4), DateTime.Now); // date range
>
>
> Okay, so here's the problem... what if I have the following
> procedure :
>
> public void DoSomething(object o)
> {
> IMinMax<> mm = (IMinMax<>) o; // this doesn't work
>
> // do something with mm.Min and mm.Max here
> }
>
> and I want to call the procedure as follows :
>
> DoSomething(intMinMax);
> DoSomething(dateMinMax);
>
>
> How do we go about doing something with Min and Max? Obviously there's
> a lot of meat missing in the code and I simplified it quite
> unrealistically for the purpose of this newsgroup so please no
> questions as to why I would want to do it... this comes up all the
> time in one form or another.
>
> I guess the real question is... once you've cast a generic interface
> to an object, how do you go about extracting its information at run-
> time? In my case I happen to know the type at runtime but the
> following modified method still doesn't work :
>
> public void DoSomething(Type t, object o)
> {
> IMinMax<t> mm = (IMinMax<t>) o; // still doesn't work
>
> // do something with mm.Min and mm.Max here
> }
>
>
> Regards!
>
> Anthony
>


From: Jon Skeet [C# MVP] on
Sheng Jiang[MVP] <sheng_jiang(a)hotmail.com.discuss> wrote:
> Your struct (or value type) is boxed and the type information seems lost
> when it is converted to object..

No, type information is certainly *not* lost when it's boxed. Just try
unboxing something to the wrong type - you'll find out soon enough.

--
Jon Skeet - <skeet(a)pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
From: Sheng Jiang[MVP] on
It seems he did not specify the type for the generics
this program runs fine
static void Main(string[] args)
{
IMinMax<int> intMinMax = new MinMax<int>(0, 100); // percentage
range
IMinMax<DateTime> dateMinMax = new MinMax<DateTime>(new
DateTime(1973, 10,
4), DateTime.Now); // date range
DoSomething<int>(intMinMax);
DoSomething<DateTime>(dateMinMax);

}
public static void DoSomething<T>(object o)
{
IMinMax<T> mm = (IMinMax<T>) o;

// do something with mm.Min and mm.Max here
}

--
Sheng Jiang
Microsoft MVP in VC++
"Jon Skeet [C# MVP]" <skeet(a)pobox.com> wrote in message
news:MPG.210753e322b7b8832f0(a)msnews.microsoft.com...
> Sheng Jiang[MVP] <sheng_jiang(a)hotmail.com.discuss> wrote:
> > Your struct (or value type) is boxed and the type information seems lost
> > when it is converted to object..
>
> No, type information is certainly *not* lost when it's boxed. Just try
> unboxing something to the wrong type - you'll find out soon enough.
>
> --
> Jon Skeet - <skeet(a)pobox.com>
> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
> If replying to the group, please do not mail me too


From: Jon Skeet [C# MVP] on
Sheng Jiang[MVP] <sheng_jiang(a)hotmail.com.discuss> wrote:
> It seems he did not specify the type for the generics
> this program runs fine

That still doesn't mean that boxing loses type information as you
claimed.

> static void Main(string[] args)
> {
> IMinMax<int> intMinMax = new MinMax<int>(0, 100); // percentage
> range
> IMinMax<DateTime> dateMinMax = new MinMax<DateTime>(new
> DateTime(1973, 10,
> 4), DateTime.Now); // date range
> DoSomething<int>(intMinMax);
> DoSomething<DateTime>(dateMinMax);
>
> }
> public static void DoSomething<T>(object o)
> {
> IMinMax<T> mm = (IMinMax<T>) o;
>
> // do something with mm.Min and mm.Max here
> }

Yes, but if he changed DoSomething<T> to accept IMinMax<T> directly,
there'd be no need for the cast, he'd gain more compile-time type
safety, and he wouldn't have to specify the type parameter at the call
site.

--
Jon Skeet - <skeet(a)pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too