25
public sealed interface IMyInterface
{
}

Gives "The modified 'sealed' is not valid for this item"

I can understand in some ways that an interface must be descendable otherwise the class cannot implement it.

But why can I not specify that an interface should not have a sub interface defined or is there a way, just not with sealed?

Edit

I should have made some effort to explain why I would want this. I often see interface inheritence chains where the dev should be using composition instead. Sealed is ideal for this in classes and I wondered if there was a way to enforce the same for interfaces. As unnessasary inheritence makes it harder to refactor and maintain in my opinion.

Edit 2

On reflection of the comments and posts, interface inheritence trees can't be anywhere near as complex as object inheritence trees. As when you are deriving from another interface IX all you are saying is "must also implement IX". And preventing that has no benefit.

weston
  • 54,145
  • 21
  • 145
  • 203
  • What would you use this for? You mean that you'd expect a sealed interface to be able to be inherited from, but without the inheriting class being able to create new member functions? Or something else? – Mr Lister Mar 27 '12 at 13:42
  • 1
    @MrLister: The only possible meaning i can think of that might make some sense, is to prevent *interfaces* deriving from the interface. – George Duckett Mar 27 '12 at 13:44
  • Since this is the first time I ever saw this question pop up, I expect nobody ever needed this feature, and this immediately answers your question: Nobody implemented this feature, because nobody has ever needed it yet :-) – Steven Mar 27 '12 at 13:47
  • 2
    I'm with you, Weston, because there's a distinct difference between class inheritance and interface implementation. If an interface were sealed it would mean to me you couldn't subclass an interface, but that doesn't imply anything differently about implementing it in a class. Inherit and implement are two separate animals. – Brad Rem Mar 27 '12 at 13:49

8 Answers8

29

The purpose of sealing a class, or a virtual method of a class, is to lower your costs. Designing for inheritance is expensive, and if you do not do it correctly, it is dangerous. There are security, correctness and robustness consequences to improperly designing for inheritance, so if you do not intend to design for inheritance, it is wise to seal your class and thereby avoid the costs associated with designing for inheritance.

Classes need to be designed for inheritance because they have implementation details. Interfaces have no implementation details. There is no cost associated with interfaces being inheritable. And therefore there is no incentive to add the feature of allowing interfaces to be sealed.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    Would there be no cost benefit to refactoring and maintainence by limiting interface inheritence chains? – weston Mar 27 '12 at 14:10
  • @weston: I don't know of any. If you do, say so! – Eric Lippert Mar 27 '12 at 14:37
  • I could see some use for being able to define an interface in a manner that would forbid anyone from implementing it outside the assembly wherein it was defined. That wouldn't really match the behavior of a "sealed" keyword, but would help compel use of composition rather than inheritance (the OP's goal), and would also help in cases where one might use an abstract class except that some implementations need to inherit other unrelated classes. I know compilers won't allow one to define an interface which reference `internal` members; what would happen if such an interface were defined in CIL? – supercat Mar 27 '12 at 16:05
  • @supercat this is possible in c#. Just define the interface as internal. All implementers must use explicit interface implementations if any of the signatures contain types which are themselves internal but it all works fine. – ShuggyCoUk Mar 27 '12 at 16:07
  • 1
    @ShuggyCoUk: If an interface is defined as `internal`, is there any way type-safe way to pass instances to external code and have them pass them back? Consider the scenario, class `UsCheckingAccount`, derived from `UsBankAccount`, and `FrenchCheckingAccount`, derived from `FrenchBankAccount`, are in an assembly. I'd like to define an `ICheckingAccount` which could be either of them, but have code which accepts an `ICheckingAccount` know that it's actually one of those, rather than some other arbitrary class. (Yes, I know, class inheritance is not real security). – supercat Mar 27 '12 at 16:58
  • @supercat. I'm not entirely clear what you're asking (which is likely a consequence of the short form comments) you might want to make it a question. Certainly any type/interface which is internal cannot be exposed (included in the signature of anything public) in a compile time known way but I'm not sure if that's what you're asking. – ShuggyCoUk Mar 28 '12 at 09:17
  • @ShuggyCoUk: Basically, the goal would be for a module to expose an interface without having to expose everything therein or allow other modules to produce implementations thereof. I'm not sure it's worth a question since (1) I know it isn't possible to do that in type-safe fashion in vb or C#; (2) the number of people who would know what would happen if one tried to do it in CIL is pretty small; and (3) since I don't program in CIL, the question would be somewhat theoretical (i.e. is it a language restriction or a CLI/CLR restriction)? – supercat Mar 28 '12 at 17:29
  • @supercat sounds like a fun question, but may be covered by some of the "what can you do in CLI but not c#" answers... – ShuggyCoUk Mar 29 '12 at 08:46
  • I'd like to add my vote for being able to mark that an interface may not be inherited-from. People comment that interfaces have no 'behavior' and so can't be "sealed" (ok, then some other keyword would be fine), but another use for interfaces in complex projects is for tagging cross-cutting classes of related objects for membership testing, i.e. with 'is'. In fact, some such interfaces contain no methods. In this situation it would be nice to express that the tag in question is intended as a logical leaf. 'internal' doesn't say the same thing. – Glenn Slayden Jul 25 '12 at 03:35
  • 1
    @GlennSlayden "tagging" classes sounds like a job for attributes, not interfaces – Dave Cousineau May 31 '14 at 23:09
  • @EricLippert "Interfaces have no implementation details" this is not entirely correct as in Kotlin interfaces can have implemented methods – David Aleksanyan Oct 05 '19 at 17:56
  • 1
    The question is about c# not java or kotlin. However c# will get interfaces with implementations soon so the answer will need updating. – Eric Lippert Oct 05 '19 at 18:13
14

It would just be confusing. Using the standard syntax, it would imply that you cannot implement the interface. Also, interfaces don't contain any functionality or fields, so there is no practical use in sealing it. An interface is more or less a contract.

Sealing an interface from "interface inheritance" would not do anything, since people could just implement your interface and the other one that would have inherited your interface.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
5

sealed in the context of an interface would mean no class can implement this interface. That would be useless, hence its not allowed.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 1
    What about interfaces that can derive from an interface? I could see how `sealed` could make sense from that point of view. However there's probably a reason other than this that makes it not make sense like not gaining anything from such a restriction. – George Duckett Mar 27 '12 at 13:42
1

The sealed keyword is simply not designed (and makes no sense) for interfaces. See the msdn documentation http://msdn.microsoft.com/en-us/library/88c54tsw(v=vs.71).aspx

Dave S
  • 775
  • 5
  • 7
0

Sealed is a keyword for a class. The goal of interfaces is for classes to implement any contracts they define. You can seal the class that implements an interface, but sealing an interface would be of little use.

Ta01
  • 31,040
  • 13
  • 70
  • 99
0

Interfaces is your Application Contract...When you don't need to your contract why you define it?

M.Azad
  • 3,673
  • 8
  • 47
  • 77
0

One of the primary purposes of sealing a class is to require any storage locations of that class to hold instances of that precise type, rather than a derived type. Even though most code won't mind when derived-type objects are substituted for base-type objects, there are many situations where such substitution can be problematic. For example, some classes include a function to perform a relative comparison with another object of the same type, with the expectation that the comparison results will yield a sortable sequence. If types Bar and Boz both derive from Foo, and use any Bar-specific or Boz-specific fields in the comparison, it may be impossible to sensibly sort sequences holding a mixture of Bar and Boz instances.

Such a purpose would not exist with interfaces, since by their nature interfaces are designed to be implemented by multiple classes. An interface which couldn't be implemented by any classes would be useless, and an interface which could only be implemented by one class would be pointless (if IFoo can't be anything other than a Foo, one might as well simply use Foo everyplace one would be inclined to use IFoo).

There would be some usefulness to restricting implementations of an interface to the module where it's defined, and/or allowing interfaces to have internal members. I don't know any particular reason why that isn't allowed, nor even whether allowing or disallowing such things would have been "easier" or "harder" than forbidding them.

supercat
  • 77,689
  • 9
  • 166
  • 211
-1

To me, interface implies an abstract keyword; so if an interface would be sealed, it would be sealed abstract what seems to be a contradiction.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 1
    FYI, a "static" class is logically both sealed and abstract; you cannot inherit from it, and you cannot create an instance. – Eric Lippert Mar 27 '12 at 13:52
  • 1
    Thanks, Eric. Arguing with a compiler developer always makes me feel really small and green :-) – Uwe Keim Mar 27 '12 at 14:02