Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class constraint must come before any other constraints

Tags:

c#

class

generics

I am attempting to create the following class name signature:

public class MyClass<T> where T : struct, MyBase

(I am using struct to constrain to Enums)

I am getting error

The class type constraint 'MyBase' must come before any other constraints

I understand the message, however, rearranging the code I cannot get past that or some other syntax error. How can I fix that line if at all?

If I have to, I will remove struct.

Thank you

like image 529
Valamas Avatar asked Feb 01 '12 00:02

Valamas


3 Answers

Constraints are "and-ed" together; all the constraints must be satisfied.

Under what circumstances can T be both a non-nullable value type and also be implicitly convertible to the class MyBase via identity, boxing or reference conversion?

There are no such circumstances, so there is no possible type argument that will satisfy T's constraints. Rather than letting you define a set of constraints that cannot be met, the compiler simply disallows it. You cannot state that you require both the struct constraint and a class type constraint.

I am using struct to constrain to Enums

That illustrates my point. Since there are no enums that inherit from MyBase, the constraint could not possibly be met.

Can you describe for me what you thought this meant? For example, did you think that it meant "any non-nullable value type or any type that is convertible to MyBase"? I am interested to learn why people believe false things about C# so that I can try to improve it.

UPDATE: Ah, I see -- MyBase is intended to be the base class of MyClass<T>, not the base class of T. In C#, it goes:

class [class name] < [generic type parameters] >
    : [base classes and interfaces]
    where [type parameter] : [constraints]

You have to put the base classes and interfaces before the constraints, otherwise the compiler thinks that they are the constraints.

like image 167
Eric Lippert Avatar answered Nov 08 '22 07:11

Eric Lippert


Did you mean class MyClass<T> : MyBase where T : struct?

like image 39
Ben Voigt Avatar answered Nov 08 '22 05:11

Ben Voigt


You're defining <T> as two different types. struct is a value type where as MyBase is a class referring to a reference type. It's not something that is interchangeable.

In this case it would be either:

public class MyClass<T> where T : struct

or

public class MyClass<T> where T : MyBase

Here is so more information regarding generics and how to use them.

like image 45
Gabe Avatar answered Nov 08 '22 07:11

Gabe