views:

467

answers:

5

Can you guess what is the reason to not allow sealed classes for type-constraints in generics? I only have one explanation is to give opportunity to use naked constraints.

Sorry, for editing.

I think you need to rephrase the question title. It should be "Why we can’t use sealed classes as generic constraints?" – this.__curious_geek 13 mins ago

Yes you're right, my question is "Why we can’t use sealed classes as generic constraints?"

+5  A: 

Are you talking about something like this:

class NonSealedClass
{
}

class Test<T> where T : NonSealedClass
{
}

Because it's perfectly legal.

Aviad P.
What are you trying to explain with this code-snippet ?
this. __curious_geek
He mentioned using a non-sealed class as a generic constraint, I guess he probably meant a sealed class...
Aviad P.
It was my mistake he answered for my incorrect question.
G2
+23  A: 

If the class is sealed it cannot be inherited. If it cannot be inherited it'd be the only type valid for the generic type argument [assuming if allowed to be a type argument]. If it is the only generic type argument then there's no point in making it generic! You can simply code against the type in non-generic class.

Here's some code for this.

public class A
{
    public A() { }
}

public sealed class B : A
{
    public B() { }
}

public class C<T>
        where T : B
{
    public C() { }
}

This will give compiler error: 'B' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.

In addition to this, You can also not have a static class as generic type-constraint. The reason is simple. Static classes are marked as abstract and sealed in compiled IL which can be neither instantiated nor inherited.

Here's the code for this.

public class D<T>
        where T : X
{
    public D() { }
}

public static class X
{
}

This will give compiler error:'X': static classes cannot be used as constraints.

this. __curious_geek
+1 - Would have never thought on this!
Konamiman
Generics is a way to use algorithms universally and to get better performance. So I slightly disagree with your point about inheritance.
G2
But there's absolutely now way that you could instantiate a C object of any type other than C<B>. Because B is sealed it can have no subclasses, thus there is no other type that will match "where T : B". Therefore, the type T will always be B; otherwise, the constraint fails.If your generic code is constrained so that it applies to exactly one type, is it still generic? :)
RAOF
+1  A: 

A naked constraint is where one generic type inherits from another e.g.

where X:Y

One generic parameter derives from another generic parameter

class Foo<T>
{
    Foo<S> SubsetFoo<S>() where S : T {  }
}

So the class cannot be sealed.

You can also inherit from generics in the normal way so you would not want them sealed.

Andrew
A: 

Just FYI this appears to be a C# limitation but not an underlying .NET limitation.

kvb
+1  A: 

Honestly, I don't quite see the point of it.

As this.__curious_geek points out in his answer, a sealed class cannot be inherited and so using one as a constraint might seem nonsensical.

But there's no guarantee that a sealed class will never be "unsealed" -- i.e., that the developer might rearrange its implementation to make it more amenable to inheritance and then remove the sealed modifier from the class definition (or just flat-out remove the sealed keyword for no reason at all).

I know a lot of developers actually encourage this practice: not removing the sealed keyword per se, but rather adding the sealed keyword liberally and only supporting inheritance when the decision to do so is made explicitly (and at this point, yes, removing the sealed keyword).

So I'm not sure why you couldn't use the type of a sealed class as a generic constraint. After all, you could always use the type of a class that just happens to not have any derived classes, even though it's not sealed. The two scenarios don't seem all that different to me.

I'm probably missing something, though. I'm sure Eric Lippert could give a pretty killer explanation.

Dan Tao