Home All Groups Group Topic Archive Search About
Author
13 Jan 2007 12:54 AM
Kevin Burton
I have an interface that I am trying to make the generic constraints as
restictive as possible so that the generic types are not what is expected. I
get two errors:

1) Indicates that the contraint type cannot be sealed. How can I get around
this?

2) I get an error that a particular type must come before other constraints.
I am not sure how to order the constraints. I was not even aware from the
documentation that there was a order restriction on the constraints.

After getting these errors I am tempted to remove all of the constaints.
Surely there is a better way. Any experts on contraints and generic types?

Thank you.

Kevin

Author
13 Jan 2007 12:48 PM
Barry Kelly
Kevin Burton wrote:

> I have an interface that I am trying to make the generic constraints as
> restictive as possible so that the generic types are not what is expected. I
> get two errors:
>
> 1) Indicates that the contraint type cannot be sealed. How can I get around
> this?

Why would you want to? E.g.:

sealed class S {}
class C<T> where T : S {}

.... in this case, C<> can only ever be instantiated with S, since
nothing can derive from S. So what's the point in it being generic then?

> 2) I get an error that a particular type must come before other constraints.
> I am not sure how to order the constraints. I was not even aware from the
> documentation that there was a order restriction on the constraints.

Can you show an example?

-- Barry

Author
13 Jan 2007 6:00 PM
Kevin Burton
One of the reasons that I would like to have a generic type from a sealed
type is to return that type. For example

interface ISample<T> where T : A,B,new()
{
      void DoSomething();
      T ReturnSomething();
}

Now when I implement ReturnSomething I will get the type T and not an
object. Since T cannot be sealed this really limits the types the T can be.

interface ISample<T> where T : a,b,c,d,new()
{
.. . . . .
}

The error that I get is not on a but it says that the constraint b should be
first.
The specific error (in a real class) that I get is:

The class type constraint
'....WebServices.BsiServices.DataContracts.GetCatalogsRequestType' must come
before any other constraints

The first par of the code looks like:

    public interface IBsiMessageHandler<Q, A>
        where Q : GetSiteConfigurationRequestType, GetCatalogsRequestType,
GetCategoriesRequestType, GetCampaignRequestType, SearchRequestType,
GetProductDetailRequestType, GetBasketRequestType,
GetShippingRatesRequestType, CreateGuestOrderRequestType,
CreateNewAcctOrderRequestType, CreateMemberOrderRequestType,
GetUserAddressListRequestType, GetHintRequestType,
GetUserInformationRequestType, GetAddressesRequestType,
GetOrderReceiptRequestType, GetOrderListRequestType, AddToBasketRequestType,
ApplyCouponRequestType, UpdateBasketRequestType, LoginUserRequestType,
ResetPasswordRequestType, UpdateUserInformationRequestType,
UpdateAddressRequestType, AddAddressRequestType,
ChangeUserPasswordRequestType, InitiateReturnRequestType, new ()
        where A : GetSiteConfigurationResponseType, GetCatalogsResponseType,
GetCategoriesResponseType, GetCampaignResponseType, SearchResponseType,
GetProductDetailResponseType, GetBasketResponseType,
GetShippingRatesResponseType, CreateGuestOrderResponseType,
CreateNewAcctOrderResponseType, CreateMemberOrderResponseType,
GetUserAddressListResponseType, GetHintResponseType,
GetUserInformationResponseType, GetAddressesResponseType,
GetOrderReceiptResponseType, GetOrderListResponseType,
AddToBasketResponseType, ApplyCouponResponseType, UpdateBasketResponseType,
LoginUserResponseType, ResetPasswordResponseType,
UpdateUserInformationResponseType, UpdateAddressResponseType,
AddAddressResponseType, ChangeUserPasswordResponseType,
InitiateReturnResponseType, new ()
    {


Thank you.

Kevin

Show quote
"Barry Kelly" wrote:

> Kevin Burton wrote:
>
> > I have an interface that I am trying to make the generic constraints as
> > restictive as possible so that the generic types are not what is expected. I
> > get two errors:
> >
> > 1) Indicates that the contraint type cannot be sealed. How can I get around
> > this?
>
> Why would you want to? E.g.:
>
> sealed class S {}
> class C<T> where T : S {}
>
> .... in this case, C<> can only ever be instantiated with S, since
> nothing can derive from S. So what's the point in it being generic then?
>
> > 2) I get an error that a particular type must come before other constraints.
> > I am not sure how to order the constraints. I was not even aware from the
> > documentation that there was a order restriction on the constraints.
>
> Can you show an example?
>
> -- Barry
>
> --
> http://barrkel.blogspot.com/
>
Author
13 Jan 2007 10:07 PM
Barry Kelly
Kevin Burton wrote:

> One of the reasons that I would like to have a generic type from a sealed
> type is to return that type. For example
>
> interface ISample<T> where T : A,B,new()
> {
>       void DoSomething();
>       T ReturnSomething();
> }
>
> Now when I implement ReturnSomething I will get the type T and not an
> object. Since T cannot be sealed this really limits the types the T can be.

If A is sealed, then the only thing T can ever be is A (since B must be
an interface, because you can't have two class constraints). Therefore,
replace "T ReturnSomething()" with "A ReturnSomething()", and remove the
generic parameter altogether.

Show quote
> interface ISample<T> where T : a,b,c,d,new()

> The error that I get is not on a but it says that the constraint b should be
> first.
> The specific error (in a real class) that I get is:
>
> The class type constraint
> '....WebServices.BsiServices.DataContracts.GetCatalogsRequestType' must come
> before any other constraints
>
> The first par of the code looks like:
>
>     public interface IBsiMessageHandler<Q, A>
>         where Q : GetSiteConfigurationRequestType, GetCatalogsRequestType,

Ah - now the cause of the confusion is clear.

The main point of .NET's generic constraints is to allow you to access
members on the types without knowing the concrete type. They aren't
really there to limit the scope of instantiation in an itemized way;
rather, their purpose is to limit the possibilities of the parameter and
thereby give the compiler more information.

When you limit generic parameter T to (say) type Foo, you can then
access all of Foo's methods on values of type T in the body of the class
definition. In order for the compiler to verify that this is always
safe, those methods must exist on some class or interface constraint on
the generic parameter, and all types used as type arguments to the
generic type must implement / descend from the types listed in the
constraints. That's how it all hangs together.

You can only have at most one class constraint and it must be first
(this is what the error is saying), and all the following constraints
must be interfaces, or you can end with the 'new()' constraint.

-- Barry


AddThis Social Bookmark Button