Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / December 2007

Tip: Looking for answers? Try searching our database.

Generics - How to ctype an instance of a generic class to something that I can use

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrew Backer - 17 Dec 2007 22:49 GMT
I hope someone out there can help me with this, because I am stuck.

My problem is that I have an instance of a generic class, but I don't know
ahead of time what the type parameter used was.  In my case the type must
derive from a class, like UserControl, so I at least know I should be able
to use that.  

I can not figure out a way to get this as an instance of the generic class,
but with the base class as the type parameter.  I am looking to do something
like this :

..Dim formRef as Form = /get-reference-to-mycontainer-instance/
..If ( TypeOf formRef Is MyContainer(Of UserControl) ) Then
...... Dim a As MyContainer(Of UserControl) = CType(formRef, MyContainer(Of
UserControl))
...... do stuff
..End If

Here is the generic class:
-------
..Public Class MyContainer(Of T As {UserControl, New})
......Inherits System.Windows.Forms.Form
......
..End Class

Is there any way to do something like this?  Even something ugly?

Thanks,
//Andrew
Jon Skeet [C# MVP] - 17 Dec 2007 23:00 GMT
<Andrew Backer
</O=MARINCOUNTY/OU=CIVICCENTER/CN=RECIPIENTS/CN=ABACKER>> wrote:
> I hope someone out there can help me with this, because I am stuck.
>
[quoted text clipped - 5 lines]
> I can not figure out a way to get this as an instance of the generic class,
> but with the base class as the type parameter.

You can't - generics don't support covariance/contravariance. So, for
example, a List<string> isn't compatible with List<object>. In
particular, imagine what would happen if you tried to add a new plain
object to it...

See Eric Lippert's blog for more information on this:

http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravar
iance/default.aspx

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrew Backer - 18 Dec 2007 00:22 GMT
Actually, I do read his blog, one of the few from MS.  It usually hurts my
brain, and the sense it makes is only flitting.  I went back and read the
ones that I thought might be relevant, and here is his quote:

//Why is this broken? Because it should always be legal to put a Turtle into
an array of Animals. With array covariance in the language and runtime you
cannot guarantee that an array of Animals can accept a Turtle (animal->reptile->tutrle)
because the backing store might actually be an array of Giraffes (animal->mamal->giraffe).
//  Parens are mine.

So basically, I have this _thing_, and there is nothing anywhere that I can
convert it to in order to call methods on it.   I can't convert it to the
base class, and call base class methods.  I recognize the similarity, but
something in me won't see why it is the same case.  Is it not allowed because,
somehow at some point I could write to that object (which I used the generic
for) with a type that would be contravaint?, ie, I could theoretically try
to write a turtle into my giraffe, and the compiler can't tell that I am
not going to do that, so it just doesn't allow the conversion at all?

Sorry for the muddled thought.  It makes sense just enough that I get it,
but I can't write it properly.  In any case, I am not doing any thing dangerious
in this class, the only New or assignment happens in the constructor basically,
but the compiler can't guarantee that will be the case in the future.  Arg.

I read I can do it by poking at Ms.Vb.CompilerServices.Conversions, but I
don't think thats a good idea.

Thanks for the re-pointer =)

//Andrew

>> I hope someone out there can help me with this, because I am stuck.
>>
[quoted text clipped - 15 lines]
> http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contrava
> r iance/default.aspx
Jon Skeet [C# MVP] - 18 Dec 2007 00:57 GMT
> Actually, I do read his blog, one of the few from MS.  It usually hurts my
> brain, and the sense it makes is only flitting.

I know what you mean. He's clearly a very smart cookie though - I'm
glad it's him and not me that has to work these things out :)

> So basically, I have this _thing_, and there is nothing anywhere that I can
> convert it to in order to call methods on it.   I can't convert it to the
[quoted text clipped - 4 lines]
> to write a turtle into my giraffe, and the compiler can't tell that I am
> not going to do that, so it just doesn't allow the conversion at all?

Sort of. It's basically that if you have Foo<T> and Foo<S> and S
derives from T, there's no guarantee that all the operations on Foo<T>
are available on Foo<S>.

However, help is at hand - a generic method may be just what you need.
A VB programmer can give you the VB syntax (I won't even try it -
getting it wrong would be worse than not trying) but if you can make
the method using it generic, you may be able to do something like:

void DoSomething<T>(MyContainer<T> formRef)
   where T : UserControl, new()
{
   // Now you can do things with formRef
}

<snip>

It may not help, but it just might do...

> I read I can do it by poking at Ms.Vb.CompilerServices.Conversions, but I
> don't think thats a good idea.

Hmm... it sounds unlikely to me, to be honest. The CLR understands
covariance/contravariance on interfaces, but that's all as far as I'm
aware. Of course, VB could do it all with late binding, but that
doesn't sound like a good idea either.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Andrew Backer - 18 Dec 2007 22:18 GMT
I think this is where I read about it:  http://journal.nullschool.net/2005/08/04/latectype-a-strongly-typed-latebound-co
nversion-operator/


I my case it is a little annoying, because the thing that I use is part of
the class itself, and has nothing to do with the type parameter, but I can't
convert anything to anything at all.  Shucks.  It turns out that in this
instance I can actually remove the offending code, so the problem is "solved."

//Andrew

> It may not help, but it just might do...
>
[quoted text clipped - 5 lines]
> aware. Of course, VB could do it all with late binding, but that
> doesn't sound like a good idea either.
Patrice - 19 Dec 2007 12:52 GMT
So you could just use the fact that each element inherits from a user
control to do something such as :

For Each Element As UserControl In formRef
   ' Do something with Element
Next

without casting the list itself...

You may want to explain your overall goal. For now I'm not sure to see why
you are trying to cast this list. If the problem is to find out what is the
type of an element you could likely expose an ElementType property that
would return this...

--
Patrice

"Andrew Backer" </O=MARINCOUNTY/OU=CIVICCENTER/CN=RECIPIENTS/CN=ABACKER> a
écrit dans le message de news:
67f4065d1a9a88ca0ed330e17f58@news.microsoft.com...
>I hope someone out there can help me with this, because I am stuck.
>
[quoted text clipped - 23 lines]
> Thanks,
> //Andrew

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.