HighTechTalks DotNet Forums  

Casting Rules

Dotnet Framework microsoft.public.dotnet.framework


Discuss Casting Rules in the Dotnet Framework forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Aeden Jameson
 
Posts: n/a

Default Casting Rules - 11-02-2007 , 06:57 PM






Suppose I have the follwing


Public Interface IEntity

End Interface


Public Class TestEntity
Implements IEntity

End Class


Public Interface IRepository(Of T As {IEntity})

End Interface


Public Interface IConcreteRepository
Inherits IRepository(Of TestEntity)
End Interface

Public Class ConcreteRepository
Implements IConcreteRepository
End Class


Public Class Factory
Public Shared Function Create(Of TRepository As {Class,
IRepository(Of TEntity)}, TEntity As {IEntity})()
Return New ConcreteRepository()
End Function
End Class

I get casting exception on the line

Dim Repository As IRepository(Of IEntity) = Factory.Create(Of
IConcreteRepository, TestEntity)()


What am I missing?


The exception states

Unable to cast object of type 'ConcreteRepository' to type
'IRepository`1[IEntity]'.


Cheers,
Aeden


Reply With Quote
  #2  
Old   
Peter Duniho
 
Posts: n/a

Default Re: Casting Rules - 11-02-2007 , 07:40 PM






On 2007-11-02 15:57:23 -0700, Aeden Jameson <aeden.jameson (AT) gmail (DOT) com> said:

Quote:
[...]
I get casting exception on the line

Dim Repository As IRepository(Of IEntity) = Factory.Create(Of
IConcreteRepository, TestEntity)()

What am I missing?

The exception states

Unable to cast object of type 'ConcreteRepository' to type
'IRepository`1[IEntity]'.
I believe this is because generics don't support covariant generics.
Your ConcreteRepository class implements IConcreteRepository, which
inherits IRepository<TestEntity>, and not IRepository<IEntity>. You
would need the latter in order to successfully perform the cast.

The reasoning behind this has to do with what a generic class _could_
do with the concrete type for the class. In particular, if you could
cast down to a base class like that, then the possibility would arise
that something in the generic class would replaces some instance of
TestEntity with some instance of a different IEntity-derived class,
which would cause a problem later in the code that had the
TestEntity-specific concrete class.

By requiring the generic type parameter to always be the actual type,
this sort of problem is avoided. It does lead to less-flexible code
such as in the example you're running into, but along with that comes
compile-time type safety.

If you don't want compile-time type safety, you should either not use
generics, or make the IRepository<> generic use IEntity instead of
TestEntity.

Pete



Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.