-3

I really need a logical explanation for that. Why did they do it? Why is using a sealed type as a constraint is not a good practice? I need the same function running for some types, and they happen to be sealed, what's wrong with that? and is there a way around it?

ByoTic
  • 333
  • 1
  • 4
  • 16
  • Your question is duplicate of [Why can't we use sealed classes as generic constraints](http://stackoverflow.com/questions/1945085/why-cant-we-use-sealed-classes-as-generic-constraints) as asked. It is possible that you are looking for something else (possibly overloading like `int Foo(MyType1 arg){...} int Foo(MyType2 arg) {...}....` ), but you need to clarify your post (or better ask separate question which clearly states what you want and may link to this as explanation what you've tried) – Alexei Levenkov Sep 02 '14 at 21:22

2 Answers2

2

A sealed type cannot be derived from (MSDN), so using one as a generic type constraint makes no sense. The generic parameter could only ever be of that type.

You might as well use that type instead of your generic type argument in the class, the effect would be the same. Hence, the restriction.

To look at why you can't constrain to types that don't inherit from the constrained type, consider what you want to be allowed:

public void MyFunction(T arg) where T : Cat or Car
{
}

I made up the non-existent "or" keyword so that you can have the feature. Now, lets say we try to use the arg variable. What is it? Is it a Cat, or a Car? Say I want to write this:

public void MyFunction(T arg) where T : Cat or Car
{
     arg.Eat();
}

That works fine if arg is a Cat, but would have nothing to call if it were a Car. Same with any method on Car. By forcing used types to derive from the constrained type, you are guaranteed that they will have any method, property, or variable that is on that type, so the code you write is type-safe.

public void MyFunction(T arg) where T : IAnimal
{
    arg.Eat(); //Guaranteed to work!
}

By allowing it the other way, you have no safety, so it is not allowed.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • but I want to use several types that are not inheriting from each other... – ByoTic Sep 02 '14 at 20:43
  • 1
    @user3050072 But without constraining to each individual type, how would you know what methods/properties they have? At that point, you might as well make overloads for each one, since the type system won't let you cast. – BradleyDotNET Sep 02 '14 at 20:46
  • 3
    @user3050072 You've misunderstood the generic type constraint then, because you couldn't do that even if the types weren't sealed. Consider making an interface that all your classes inherit. – Casey Sep 02 '14 at 20:46
  • @user3050072 Edited to expound on the "why" of not allowing the "OR" version of type constraints. – BradleyDotNET Sep 02 '14 at 21:01
0

If the type is sealed the the generic argument would only ever be able to be exactly that one type. There'd be no point in using generics at all. Just scrap the generic argument and use that one type anywhere you would otherwise have used the generic argument.

Generics are designed to be generic, not for use in cases where you want one specific type.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • but there is point! I want a function to work only for certain types, with the exact same implementation. It doesn't make any sense to just overload the method with the same implementation over and over again! – ByoTic Sep 02 '14 at 20:42
  • @user3050072: If you think you have a point, please show an example as (pseudo-)code in your question. That may also help make your question unique rather than a duplicate. – O. R. Mapper Sep 02 '14 at 20:44
  • 2
    @user3050072 Constraining the generic argument to a sealed type doesn't do that. Constraints are ANDed together, not ORed. You should use an interface, that's what they're for. – Servy Sep 02 '14 at 20:44
  • take a picture of my code: http://puu.sh/biMRZ/ee25a05def.png – ByoTic Sep 02 '14 at 20:46
  • 1
    @user3050072 You will never, ever, have a type that is both an `int` and a `long`. No type can ever meet those constraints. – Servy Sep 02 '14 at 20:46
  • isn't there an option to OR the constraints? – ByoTic Sep 02 '14 at 20:47
  • 1
    @user3050072: As Servy explained, that means in your concrete case that `T` must equal or inherit from `int` **and** be equal to or inherit from `double` **and** ... see where you're going wrong? – O. R. Mapper Sep 02 '14 at 20:47
  • @user3050072: No, and while I'm sure this has been asked before - searching for link - note that the sole point of generic constraints is for the implementor of the generic code to know what `T` offers. If `T` is subject to one or more constraint, those constraints indicate what can be done with `T` (e.g. what methods it has), but if `T` were subject to either one or another constraint, it would still be totally unclear what assumptions are actually guaranteed about `T`. – O. R. Mapper Sep 02 '14 at 20:49
  • @user3050072 Why do you need generics at all? You're already using dynamics. Just accept object or dynamic and be done with it. What's the benefit (especially when you are returning void)? You can put a check for `arrayOfTypes.Contains(input.GetType())` at the top. – Casey Sep 02 '14 at 20:49
  • @emodendroket The difference is that your solution loses all compile type type checking, whereas he's looking to avoid that. Yes, he's using `dynamic`, but if he's already validated that the type is one of the valid types, he'll know it will succeed, thus giving him static type safety. – Servy Sep 02 '14 at 20:51
  • 1
    @user3050072 Doubt it will help you, but the numeric types *do* implement `IConvertible` so you could use that as a constraint. http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-generic-class-in-c-sharp – BradleyDotNET Sep 02 '14 at 20:52
  • @user3050072: [One such question](http://stackoverflow.com/questions/8745444/c-sharp-generic-constraints-to-include-value-types-and-strings), [another such question](http://stackoverflow.com/questions/2391968/c-sharp-generic-constraints), [yet another such question](http://stackoverflow.com/questions/10642751/excluding-types-in-the-generic-constraints-possible). – O. R. Mapper Sep 02 '14 at 20:54
  • @Servy True enough, although I wonder how likely you really are to run into an issue because of it, especially with the runtime check. – Casey Sep 02 '14 at 20:55
  • I'm creating a library, and I just want to make sure that users will know what types are allowed. With constraints this is not a problem, but with dynamic checking I need to mention the specific types that are allowed. Isn't there a solution for compile time? – ByoTic Sep 02 '14 at 20:58
  • 2
    @user3050072: Offering several overloads. That's what they're for. – O. R. Mapper Sep 02 '14 at 20:59
  • yea, but in my case there are too much of them- that just looks BAD. – ByoTic Sep 02 '14 at 21:00
  • 3
    @user3050072 Look at any of the provided math methods. They have overloads for almost every numeric type. If its good enough for the runtime, its good enough for me. – BradleyDotNET Sep 02 '14 at 21:01
  • @user3050072 You can have a private implementation that takes object and then make the overloads public if you're worried about repeating the same code over and over. – Casey Sep 02 '14 at 21:06