PC Review


Reply
Thread Tools Rate Thread

Complex Casting problem in Generics

 
 
Ajeet
Guest
Posts: n/a
 
      18th Jan 2007
hi

I am having some difficulty in casting using generics. These are the
classes.

public interface IProvider<PROF>
where PROF : IProviderProfile
{
//Some properties/methods
}

public interface IAuthenticationProvider<PROF, TOK, CRED> :
IProvider<PROF>
where PROF : IAuthenticationProviderProfile
where TOK : IToken
where CRED : ICredential
{
//Some methods.
}

public class ADAMAuthenticationProvider :
IAuthenticationProvider<ADAMAuthenticationProviderProfile,
ADAMUserToken, UsernamePasswordCredential>
{
}

The first two are interfaces. The third class is the concrete provider.
My problem is that I cannot cast an instance of
ADAMAuthenticationProvider to IProvider<IProviderProfile>.

I should note here that ADAMAuthenticationProviderProfile derives from
IAuthenticationProviderProfile which derives from IProviderProfile.
Similarly the token and credential concrete classes are derived from
the interfaces mentioned in the constraints in the 2nd interface.

What do I have to do to be able to cast it as desired? If you can give
me links that describe the solution, I will be grateful (I tried some
googling but to no luck so far).

Regards,
Ajeet.

 
Reply With Quote
 
 
 
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      18th Jan 2007
Ajeet wrote:
> I am having some difficulty in casting using generics. These are the
> classes.


<snip>

> What do I have to do to be able to cast it as desired? If you can give
> me links that describe the solution, I will be grateful (I tried some
> googling but to no luck so far).


You can't. As far as I can tell, your problem is the same one as often
bites people that you can't cast from List<string> to List<object>.
That's an easier example to work with, so I'll do so, if you don't mind


Suppose C# generics supported covariance in types. I could do:
List<string> sl = new List<string>();
List<object> ol = sl;
ol.Add (new object());

At that point I've clearly broken the idea that the list should only
contain strings.

Now, it could be that your interfaces wouldn't actually have that
problem (i.e. there wouldn't be any methods/properties exposed which
gave rise to the issue), but that's why it's disallowed.

Are you absolutely sure you need generics here in the first place?

Jon

 
Reply With Quote
 
Ajeet
Guest
Posts: n/a
 
      18th Jan 2007
Jon Skeet [C# MVP] wrote:
> Ajeet wrote:
> > I am having some difficulty in casting using generics. These are the
> > classes.

>
> <snip>
>
> > What do I have to do to be able to cast it as desired? If you can give
> > me links that describe the solution, I will be grateful (I tried some
> > googling but to no luck so far).

>
> You can't. As far as I can tell, your problem is the same one as often
> bites people that you can't cast from List<string> to List<object>.
> That's an easier example to work with, so I'll do so, if you don't mind
>
>
> Suppose C# generics supported covariance in types. I could do:
> List<string> sl = new List<string>();
> List<object> ol = sl;
> ol.Add (new object());
>
> At that point I've clearly broken the idea that the list should only
> contain strings.
>


that makes sense. I did not think of that.

Can I overload the cast operator and do this?

> Now, it could be that your interfaces wouldn't actually have that
> problem (i.e. there wouldn't be any methods/properties exposed which
> gave rise to the issue), but that's why it's disallowed.
>
> Are you absolutely sure you need generics here in the first place?
>


We deliberated quite a bit before deciding on generics, so there are
quite a few reasons for doing this. Although I admit we did not foresee
this problem occurring. Do you think there are disadvantages to using
generics?

> Jon


 
Reply With Quote
 
Ben Voigt
Guest
Posts: n/a
 
      18th Jan 2007

"Ajeet" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Jon Skeet [C# MVP] wrote:
>> Ajeet wrote:
>> > I am having some difficulty in casting using generics. These are the
>> > classes.

>>
>> <snip>
>>
>> > What do I have to do to be able to cast it as desired? If you can give
>> > me links that describe the solution, I will be grateful (I tried some
>> > googling but to no luck so far).

>>
>> You can't. As far as I can tell, your problem is the same one as often
>> bites people that you can't cast from List<string> to List<object>.
>> That's an easier example to work with, so I'll do so, if you don't mind
>>
>>
>> Suppose C# generics supported covariance in types. I could do:
>> List<string> sl = new List<string>();
>> List<object> ol = sl;
>> ol.Add (new object());
>>
>> At that point I've clearly broken the idea that the list should only
>> contain strings.
>>

>
> that makes sense. I did not think of that.
>
> Can I overload the cast operator and do this?


Should be possible, although it may be better to make an explicit conversion
function.

Something like:

public interface IProvider<PROF>
where PROF : IProviderProfile
{
private readonly PROF internalProfile;
private IProfile(PROF prov) : internalProvider(prov) {}
//Public constructors
//Some properties/methods
public IProvider<BASEPROF> Covary<BASEPROF>() where PROF : BASEPROF
{ return new IProvider<BASEPROF>(internalProfile); } // because
internalProfile casts to BASEPROF

// if IProfile has any internal state, you need to find
a way to share that too,

// possibly via pointer-to-implementation paradigm

// now you also need a generic operator==, not sure if that is possible
}


>
>> Now, it could be that your interfaces wouldn't actually have that
>> problem (i.e. there wouldn't be any methods/properties exposed which
>> gave rise to the issue), but that's why it's disallowed.
>>
>> Are you absolutely sure you need generics here in the first place?
>>

>
> We deliberated quite a bit before deciding on generics, so there are
> quite a few reasons for doing this. Although I admit we did not foresee
> this problem occurring. Do you think there are disadvantages to using
> generics?
>
>> Jon

>



 
Reply With Quote
 
Christof Nordiek
Guest
Posts: n/a
 
      18th Jan 2007
Hi Ajeet,

a solution could be, to have a non generic Interface IProvider from wich
IProvider<> derives.
Then you could cast to this Interface instead of casting to
IProvider<IProviderProfile>

public interface IProvider<PROF> : IProvider where PROF : IProviderProfile
{
}

Would this help you?

"Ajeet" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> hi
>
> I am having some difficulty in casting using generics. These are the
> classes.
>
> public interface IProvider<PROF>
> where PROF : IProviderProfile
> {
> //Some properties/methods
> }
>
> public interface IAuthenticationProvider<PROF, TOK, CRED> :
> IProvider<PROF>
> where PROF : IAuthenticationProviderProfile
> where TOK : IToken
> where CRED : ICredential
> {
> //Some methods.
> }
>
> public class ADAMAuthenticationProvider :
> IAuthenticationProvider<ADAMAuthenticationProviderProfile,
> ADAMUserToken, UsernamePasswordCredential>
> {
> }
>
> The first two are interfaces. The third class is the concrete provider.
> My problem is that I cannot cast an instance of
> ADAMAuthenticationProvider to IProvider<IProviderProfile>.
>
> I should note here that ADAMAuthenticationProviderProfile derives from
> IAuthenticationProviderProfile which derives from IProviderProfile.
> Similarly the token and credential concrete classes are derived from
> the interfaces mentioned in the constraints in the 2nd interface.
>
> What do I have to do to be able to cast it as desired? If you can give
> me links that describe the solution, I will be grateful (I tried some
> googling but to no luck so far).
>
> Regards,
> Ajeet.
>



 
Reply With Quote
 
Ajeet
Guest
Posts: n/a
 
      19th Jan 2007

Ben Voigt wrote:
> "Ajeet" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Jon Skeet [C# MVP] wrote:
> >> Ajeet wrote:
> >> > I am having some difficulty in casting using generics. These are the
> >> > classes.
> >>
> >> <snip>
> >>
> >> > What do I have to do to be able to cast it as desired? If you can give
> >> > me links that describe the solution, I will be grateful (I tried some
> >> > googling but to no luck so far).
> >>
> >> You can't. As far as I can tell, your problem is the same one as often
> >> bites people that you can't cast from List<string> to List<object>.
> >> That's an easier example to work with, so I'll do so, if you don't mind
> >>
> >>
> >> Suppose C# generics supported covariance in types. I could do:
> >> List<string> sl = new List<string>();
> >> List<object> ol = sl;
> >> ol.Add (new object());
> >>
> >> At that point I've clearly broken the idea that the list should only
> >> contain strings.
> >>

> >
> > that makes sense. I did not think of that.
> >
> > Can I overload the cast operator and do this?

>
> Should be possible, although it may be better to make an explicit conversion
> function.
>
> Something like:
>
> public interface IProvider<PROF>
> where PROF : IProviderProfile
> {
> private readonly PROF internalProfile;
> private IProfile(PROF prov) : internalProvider(prov) {}
> //Public constructors
> //Some properties/methods
> public IProvider<BASEPROF> Covary<BASEPROF>() where PROF : BASEPROF
> { return new IProvider<BASEPROF>(internalProfile); } // because
> internalProfile casts to BASEPROF
>
> // if IProfile has any internal state, you need to find
> a way to share that too,
>
> // possibly via pointer-to-implementation paradigm
>
> // now you also need a generic operator==, not sure if that is possible
> }
>


yeah .. i thought more about the explicit casting approach. There are
other drawbacks. The principal one that I see is that there will be no
runtime polymorphism anymore. Plus, if I later want to cast it back to
the original type, that would prove impossible.

Do you guys have any solution that will address these problems?

I am currently calling the methods through reflection. This makes all
the interfaces pretty much useless. I don't see a good solution to the
problem though.

>
> >
> >> Now, it could be that your interfaces wouldn't actually have that
> >> problem (i.e. there wouldn't be any methods/properties exposed which
> >> gave rise to the issue), but that's why it's disallowed.
> >>
> >> Are you absolutely sure you need generics here in the first place?
> >>

> >
> > We deliberated quite a bit before deciding on generics, so there are
> > quite a few reasons for doing this. Although I admit we did not foresee
> > this problem occurring. Do you think there are disadvantages to using
> > generics?
> >
> >> Jon

> >


 
Reply With Quote
 
Ajeet
Guest
Posts: n/a
 
      19th Jan 2007

Christof Nordiek wrote:
> Hi Ajeet,
>
> a solution could be, to have a non generic Interface IProvider from wich
> IProvider<> derives.
> Then you could cast to this Interface instead of casting to
> IProvider<IProviderProfile>
>
> public interface IProvider<PROF> : IProvider where PROF : IProviderProfile
> {
> }
>
> Would this help you?
>


No this would be of no use. I need to cast into that interface because
that interface contains some methods that I need to call. Doing this
would leave me with an empty interface which I will not be able to use.

> "Ajeet" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:(E-Mail Removed)...
> > hi
> >
> > I am having some difficulty in casting using generics. These are the
> > classes.
> >
> > public interface IProvider<PROF>
> > where PROF : IProviderProfile
> > {
> > //Some properties/methods
> > }
> >
> > public interface IAuthenticationProvider<PROF, TOK, CRED> :
> > IProvider<PROF>
> > where PROF : IAuthenticationProviderProfile
> > where TOK : IToken
> > where CRED : ICredential
> > {
> > //Some methods.
> > }
> >
> > public class ADAMAuthenticationProvider :
> > IAuthenticationProvider<ADAMAuthenticationProviderProfile,
> > ADAMUserToken, UsernamePasswordCredential>
> > {
> > }
> >
> > The first two are interfaces. The third class is the concrete provider.
> > My problem is that I cannot cast an instance of
> > ADAMAuthenticationProvider to IProvider<IProviderProfile>.
> >
> > I should note here that ADAMAuthenticationProviderProfile derives from
> > IAuthenticationProviderProfile which derives from IProviderProfile.
> > Similarly the token and credential concrete classes are derived from
> > the interfaces mentioned in the constraints in the 2nd interface.
> >
> > What do I have to do to be able to cast it as desired? If you can give
> > me links that describe the solution, I will be grateful (I tried some
> > googling but to no luck so far).
> >
> > Regards,
> > Ajeet.
> >


 
Reply With Quote
 
Christof Nordiek
Guest
Posts: n/a
 
      19th Jan 2007
"Ajeet" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
>
> Christof Nordiek wrote:
>> Hi Ajeet,
>>
>> a solution could be, to have a non generic Interface IProvider from wich
>> IProvider<> derives.
>> Then you could cast to this Interface instead of casting to
>> IProvider<IProviderProfile>
>>
>> public interface IProvider<PROF> : IProvider where PROF :
>> IProviderProfile
>> {
>> }
>>
>> Would this help you?
>>

>
> No this would be of no use. I need to cast into that interface because
> that interface contains some methods that I need to call. Doing this
> would leave me with an empty interface which I will not be able to use.
>

You can cast to the IProvider interface. Give the IProvider interface all
methods you will need in the general case. The implement them either
implicitly or explicitly by calling the resp. method with typeparameter as
return type.

public interface IProvider
{
IProviderProfile GetProfile();
void OtherMethod();
}

public interface IProvider<PROF>: IProvider where PROF : IProviderProfile
{
PROF GetProfile();
}

public class MyProvider : IProvider<MyProfile>
{
public IProviderProfile GetProfile()
{
implementation goes here.
}

IProvider.GetProfile() { return GetProfile(); }

public OtherMethod()
{
some other impl. here
}
}

will this work for you?

>> "Ajeet" <(E-Mail Removed)> schrieb im Newsbeitrag
>> news:(E-Mail Removed)...
>> > hi
>> >
>> > I am having some difficulty in casting using generics. These are the
>> > classes.
>> >
>> > public interface IProvider<PROF>
>> > where PROF : IProviderProfile
>> > {
>> > //Some properties/methods
>> > }
>> >
>> > public interface IAuthenticationProvider<PROF, TOK, CRED> :
>> > IProvider<PROF>
>> > where PROF : IAuthenticationProviderProfile
>> > where TOK : IToken
>> > where CRED : ICredential
>> > {
>> > //Some methods.
>> > }
>> >
>> > public class ADAMAuthenticationProvider :
>> > IAuthenticationProvider<ADAMAuthenticationProviderProfile,
>> > ADAMUserToken, UsernamePasswordCredential>
>> > {
>> > }
>> >
>> > The first two are interfaces. The third class is the concrete provider.
>> > My problem is that I cannot cast an instance of
>> > ADAMAuthenticationProvider to IProvider<IProviderProfile>.
>> >
>> > I should note here that ADAMAuthenticationProviderProfile derives from
>> > IAuthenticationProviderProfile which derives from IProviderProfile.
>> > Similarly the token and credential concrete classes are derived from
>> > the interfaces mentioned in the constraints in the 2nd interface.
>> >
>> > What do I have to do to be able to cast it as desired? If you can give
>> > me links that describe the solution, I will be grateful (I tried some
>> > googling but to no luck so far).
>> >
>> > Regards,
>> > Ajeet.
>> >

>



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Casting of generics? psyCK0 Microsoft C# .NET 3 25th Jan 2007 05:10 PM
Generics and casting Alexander van Doormalen Microsoft C# .NET 11 20th Mar 2006 06:26 PM
C#, Generics and casting krahenbuhl@gmail.com Microsoft C# .NET 4 7th Mar 2006 03:41 PM
Type Casting With Generics rajivpopat Microsoft C# .NET 2 12th Sep 2005 06:22 AM
Casting generics Vidar_ Microsoft C# .NET 0 4th Jun 2005 10:32 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 03:14 PM.