11

In several places (e.g. "Creating Windows Runtime Components for JavaScript, in C# and Visual Basic" on MSDN), I've seen it specified that, if you write a class in .NET that you want to use from JavaScript, then you must make it a sealed class.

This seems like an arbitrary restriction. Why can JavaScript only work with sealed classes?

Joe White
  • 94,807
  • 60
  • 220
  • 330
  • 6
    Because WinRT is built on top of COM and COM does not support inheritance. The *sealed* keyword ensures that it is crystal clear to anybody that sees the code that such a class is not extensible through inheritance. – Hans Passant Sep 20 '11 at 22:27
  • 1
    @Hans There is actually some form of inheritance supported by WinRT itself - e.g. you can inherit from `FrameworkElement` (which is itself a WinRT class) in .NET. And you don't have to mark classes defined in C++/CX as sealed, and can inherit from them also. So this seems to be a limitation only for autorhing WinRT components in .NET, not a (COM-inherited) limitation of WinRT itself. – Pavel Minaev Sep 21 '11 at 06:19
  • 4
    @Hans: COM supports inheritance. We don't allow interface inheritance in winrt interfaces though. – Larry Osterman Sep 21 '11 at 13:24
  • @LarryOsterman I feel this is bringing me closer to an answer to my question (http://stackoverflow.com/questions/9287348/why-does-adding-2nd-level-subclassed-button-controls-to-a-grid-give-e-invalidarg), but I need to know more to understand. Please have a look. – Ludvig A. Norin Feb 15 '12 at 14:29

1 Answers1

7

Windows runtime objects exposed to JavaScript applications are sealed from a JavaScript perspective - you can't add expando properties to WinRT objects. But from C++ and C#, winrt objects can be inherited if the object supports inheritance (most Xaml classes support inheritance for instance, but most others don't).

The reason that WinRT objects are sealed from JS is to ensure that the winrt object behave the same regardless of what the app has done - if an app redefines some function property on an object, it could cause other parts of the app to misbehave.

Larry Osterman
  • 16,086
  • 32
  • 60
  • Same restriction on C#, check at 40:15 in this video: http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-531T COM does not support implementation inheritance. – Hans Passant Sep 21 '11 at 14:21
  • 2
    @Hans: This has absolutely nothing to do with COM. The windows runtime is *not* COM (it has some elements of COM, but it's *very* different). The runtime DOES support inheritance - as Pavel mentioned above, you can derive from FrameWorkElement in C++/CX or C#/VB. – Larry Osterman Sep 21 '11 at 14:34
  • 3
    I can't help but do the "derives from IUnknown, does reference counting: it must be duck" test. Looking forward to you blogging about this. – Hans Passant Sep 21 '11 at 14:49
  • @LarryOsterman: "if an app redefines some function property on an object, it could cause other parts of the app to misbehave" But that's true of any environment that supports virtual methods. Yes, it's *possible* for a descendant to screw things up, if their override fails to follow the contract. That doesn't explain why JavaScript is only allowed to see sealed classes. – Joe White Sep 21 '11 at 15:59
  • "derives from IUnknown" is a lifetime management statement - yes, the windows runtime uses COM for lifetime management and IPC. Everything else is brand new. – Larry Osterman Sep 21 '11 at 19:55
  • 2
    JavaScript isn't just allowed to see sealed classes. It's just that the only non-sealed classes in the are Xaml related and thus aren't exposed to JavaScript apps. – Larry Osterman Sep 21 '11 at 19:56
  • @LarryOsterman: "the only non-sealed classes in the are Xaml related" Okay, I'll buy that for the built-in WinRT types; I've seen the same thing stated elsewhere. But why should that place restrictions on classes defined by third parties (like me)? You said above that the runtime supports inheritance, so why disallow unsealed types in JavaScript? That's my whole question: *why* was the conscious decision made to block JavaScript from seeing non-sealed, non-XAML types? – Joe White Sep 21 '11 at 22:41
  • @Hans Non-sealed WinRT classes _can_ be used from C# and _can_ be inherited from (if they weren't, you'd be unable to use `Windows.UI.Xaml` at all!); they just cannot be _defined_ in C#. – Pavel Minaev Sep 22 '11 at 01:47
  • @Joe: 3rd parties can create non sealed types - you need to use the low level authoring experience (MIDLRT) to do it. I don't believe the details of the low level experience are available yet, but the tools are in the developer preview. – Larry Osterman Sep 22 '11 at 14:11
  • 2
    I do need to make one thing clear: You'll be able to see the non sealed types from JS. But you can't derive from them - this is not supported. – Larry Osterman Sep 22 '11 at 14:12
  • @LarryOsterman: "You'll be able to see the non sealed types from JS" But the article says "The class must be sealed for JavaScript to use it". Is there some subtle distinction I'm not following? – Joe White Sep 22 '11 at 14:39
  • 1
    @Larry Low-level authoring experience is now documented at http://msdn.microsoft.com/en-us/library/hh438466(v=VS.110).aspx, at least partially so. Also, you can define non-sealed types in high-level C++/CX. On the other hand, such types seem to be not usable from JS, at least in Dev preview - you see them in JS Intellisense, but trying to activate them with `new` fails at runtime. – Pavel Minaev Sep 22 '11 at 21:58
  • @Pavel: That's WRL, which is a part of the story - you also need to have the MIDL enhancements which are not yet documented (they will be, but there's a LOT of documentation to write for Win8). As I said, JS doesn't support inheritable classes. – Larry Osterman Feb 15 '12 at 15:58