473,397 Members | 2,084 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Generic Interfaces and casting from object at runtime problem

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<intintMinMax = new MinMax<int>(0, 100); // percentage range
IMinMax<ddateMinMax = 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<tmm = (IMinMax<t>) o; // still doesn't work

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

Anthony

Jul 17 '07 #1
15 7056
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" <an**********@gmail.comwrote in message
news:11**********************@o11g2000prd.googlegr oups.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<intintMinMax = new MinMax<int>(0, 100); // percentage range
IMinMax<ddateMinMax = 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<tmm = (IMinMax<t>) o; // still doesn't work

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

Anthony

Jul 17 '07 #2
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
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 - <sk***@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
Jul 17 '07 #3
It seems he did not specify the type for the generics
this program runs fine
static void Main(string[] args)
{
IMinMax<intintMinMax = new MinMax<int>(0, 100); // percentage
range
IMinMax<DateTimedateMinMax = 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<Tmm = (IMinMax<T>) o;

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

--
Sheng Jiang
Microsoft MVP in VC++
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
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 - <sk***@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

Jul 17 '07 #4
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
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<intintMinMax = new MinMax<int>(0, 100); // percentage
range
IMinMax<DateTimedateMinMax = 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<Tmm = (IMinMax<T>) o;

// do something with mm.Min and mm.Max here
}
Yes, but if he changed DoSomething<Tto accept IMinMax<Tdirectly,
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 - <sk***@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
Jul 18 '07 #5
in Managed C++, you do not have to lose static type information when you box
a value. This is something that C# does not provide.

--
Sheng Jiang
Microsoft MVP in VC++
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
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<intintMinMax = new MinMax<int>(0, 100); //
percentage
range
IMinMax<DateTimedateMinMax = 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<Tmm = (IMinMax<T>) o;

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

Yes, but if he changed DoSomething<Tto accept IMinMax<Tdirectly,
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 - <sk***@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

Jul 18 '07 #6

http://msdn2.microsoft.com/en-us/lib...05cplus_topic7
not related to this case though
--
Sheng Jiang
Microsoft MVP in VC++
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
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<intintMinMax = new MinMax<int>(0, 100); //
percentage
range
IMinMax<DateTimedateMinMax = 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<Tmm = (IMinMax<T>) o;

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

Yes, but if he changed DoSomething<Tto accept IMinMax<Tdirectly,
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 - <sk***@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

Jul 18 '07 #7
Sheng Jiang[MVP] <sh*********@hotmail.com.discusswrote:
in Managed C++, you do not have to lose static type information when you box
a value. This is something that C# does not provide.
Ah, you mean that C++ exposes the boxed type separately from the
unboxed type? Nice.

--
Jon Skeet - <sk***@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
Jul 18 '07 #8
Hello Sheng!

Thanks for replying...

The problem with the solution you suggested is that I would have to
modify the DoSomething procedure to accept a generic type. My question
was (and given that *exact* scenario I described) how would I go about
using a generic object after it has been cast to an object and passed
as a parameter via a method that knows nothing about the generic type?
I was even generous enough to allow for the possibility of me already
knowing the generic type, but not passed in as a generic type to the
method but through a parameter of type Type as in the following :

public void DoSomething(object o, Type t)

This, of course, is a horrible example but given this exact scenario,
how would I be able to cast o back to its original form and use it?
And how would be go about doing the same if we didn't happen to have
the luxury of knowing the generic type as in the following :

public void DoSomething(object o)
{
// how do I cast o to the appropriate IMinMax<Tand use it here?
}

Regards,

Anthony

On Jul 17, 7:01 pm, "Sheng Jiang[MVP]"
<sheng_ji...@hotmail.com.discusswrote:
It seems he did not specify the type for the generics
this program runs fine
static void Main(string[] args)
{
IMinMax<intintMinMax = new MinMax<int>(0, 100); // percentage
range
IMinMax<DateTimedateMinMax = 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<Tmm = (IMinMax<T>) o;

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

--
Sheng Jiang
Microsoft MVP in VC++
"Jon Skeet [C# MVP]" <sk...@pobox.comwrote in messagenews:MP*********************@msnews.microso ft.com...
Sheng Jiang[MVP] <sheng_ji...@hotmail.com.discusswrote:
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 - <sk...@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- Hide quoted text -

- Show quoted text -

Jul 19 '07 #9
Hello Jon,

In reply to your post on the other duplicate thread (I had no idea it
was posted twice) as to why I didn't pass the generic type via the
generic method call :

public void DoSomething<T>(object o)
I can't do this because it mean making an assumption that object "o"
is of a certain generic type when that may not be the case. What if
it's just a regular old int? or a string? It could be an IMinMax<Tin
which case the T would come in handy, but what if it was a... let's
say, ISeries<T, U, V??

Regards,

Anthony

Jul 19 '07 #10
Anthony Paul <an**********@gmail.comwrote:
In reply to your post on the other duplicate thread (I had no idea it
was posted twice) as to why I didn't pass the generic type via the
generic method call :

public void DoSomething<T>(object o)

I can't do this because it mean making an assumption that object "o"
is of a certain generic type when that may not be the case. What if
it's just a regular old int? or a string? It could be an IMinMax<Tin
which case the T would come in handy, but what if it was a... let's
say, ISeries<T, U, V??
Then your cast on the first line of DoSomething is going to throw an
exception immediately.

--
Jon Skeet - <sk***@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
Jul 19 '07 #11
Yes... that's my point, it won't work. So my question is... how does
one go about doing it?

On Jul 19, 4:32 pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Anthony Paul <anthonypa...@gmail.comwrote:
In reply to your post on the other duplicate thread (I had no idea it
was posted twice) as to why I didn't pass the generic type via the
generic method call :
public void DoSomething<T>(object o)
I can't do this because it mean making an assumption that object "o"
is of a certain generic type when that may not be the case. What if
it's just a regular old int? or a string? It could be an IMinMax<Tin
which case the T would come in handy, but what if it was a... let's
say, ISeries<T, U, V??

Then your cast on the first line of DoSomething is going to throw an
exception immediately.

--
Jon Skeet - <sk...@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

Jul 20 '07 #12
Anthony Paul <an**********@gmail.comwrote:
Yes... that's my point, it won't work. So my question is... how does
one go about doing it?
Doing what, exactly? You can't pretend that something implements an
interface if it doesn't.

I originally thought that your problem was not knowing what kind of
IMinMax<Tto cast to (i.e. what to use as T). If you're wanting to use
something which *isn't* an IMinMax<Tas if it is, that's a completely
different question.

--
Jon Skeet - <sk***@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
Jul 20 '07 #13

I am looking for solution of this problem too. At this time, I use
reflection to determine the generic type of the interface and then
Invoke interface methods. But this approach generates not easy readable
code...

*** Sent via Developersdex http://www.developersdex.com ***
Jul 3 '08 #14
On Jul 3, 8:34*am, Sergey Zhukov <s...@ngs.ruwrote:
I am looking for solution of this problem too. At this time, I use
reflection to determine the generic type of the interface and then
Invoke interface methods. But this approach generates not easy readable
code...
When you're using reflection, the result is almost never readable
code. Generics do make it worse though - it's an extra dimension to
think about, effectively :(

Jon
Jul 3 '08 #15
Hi Anthony,

I've got the exact same problem. Did you find a solution in the end?

Cheers,
Sandy.
Jul 28 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: CharlesEF | last post by:
Hi All, This has me stumped. I have used a VBScript dictionary object to load column names and their values so I can use them when I build the web page. When I do this, I get the correct...
6
by: Picho | last post by:
Hi all. I have a webservice and a windows app. both of them reference the same class library called WebServiceTest.Core that defines a class called Class1. the webservice exposes a method...
2
by: cylt | last post by:
Hi, I would like to have something like that : IList<IUser> list2 = list1 as IList<IUser>; where list1 is a generic collection of User ( IList list1<User>=new List<User>() ) and where User...
13
by: DaTurk | last post by:
Hi, This is a question brought about by a solution I came up with to another question I had, which was "Dynamic object creation". So, I'm curious if you can dynamically cast an object. If you...
1
by: Anthony Paul | last post by:
Hello everyone! 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...
1
by: =?Utf-8?B?QkpT?= | last post by:
I have written a Generic method that takes an object, a type, T, and returns a System.Nullable (Of T) depending on whether or not the object IsDBNull. It was working fine until I tried to pass a...
7
by: Robert | last post by:
Thanks George, I really am grateful for attempts to be helpful, but this really doesn't answer the question in my OP. What I am looking for is an explanation of WHY things are this way (I was...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.