Ich empfehle jedem, es nicht oder nur in homöopathischen Dosen zu verwenden. Leider muss ich aus Legacy-Gründen viel damit arbeiten. Wie bereits erwähnt, wurde es für .NET 1.1 entwickelt und seitdem nicht mehr aktualisiert, hat keine Unterstützung für Generics, keine Unterstützung für Delegates, kann keine Ereignisse deklarieren usw. Es war nie sehr weit verbreitet und wird derzeit nicht mehr weiterentwickelt (obwohl Microsoft manchmal noch einen von mir eingereichten Fehler behebt). Aber das ist das kleinere Problem: Es gibt große Probleme im Compiler, gültiger Code kann ihn leicht zum Absturz bringen und dann hat man nur eine Exception, die irgendwo in den Tiefen der jsc.exe geworfen wird, ohne einen Hinweis, welche Datei den Absturz verursacht, geschweige denn welche Codezeile. Hier ist ein Beispiel dafür, was passiert (ich habe ein stark typisiertes Array in eine ICollection gecastet):
***INTERNAL COMPILER ERROR***
Microsoft.Vsa.VsaException: InternalCompilerError (0x80133021): System.NotSupportedException: Not supported in a non-reflected type.
at System.Reflection.Emit.SymbolType.GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
at System.Type.GetMember(String name, BindingFlags bindingAttr)
at Microsoft.JScript.Convert.GetToXXXXMethod(IReflect ir, Type desiredType, Boolean explicitOK)
at Microsoft.JScript.Convert.EmittedCallToConversionMethod(AST ast, ILGenerator il, Type source_type, Type target_type)
at Microsoft.JScript.Convert.Emit(AST ast, ILGenerator il, Type source_type, Type target_type, Boolean truncationPermitted)
at Microsoft.JScript.Binding.TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, Boolean construct, Boolean brackets)
at Microsoft.JScript.Lookup.TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, Boolean construct, Boolean brackets)
at Microsoft.JScript.Call.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.Binding.TranslateToILSet(ILGenerator il, AST rhvalue)
at Microsoft.JScript.Lookup.TranslateToILSet(ILGenerator il, Boolean doBoth, AST rhvalue)
at Microsoft.JScript.VariableDeclaration.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.Block.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.FunctionObject.TranslateToIL(CompilerGlobals compilerGlobals)
at Microsoft.JScript.FunctionDeclaration.TranslateToILInitializer(ILGenerator il)
at Microsoft.JScript.Block.TranslateToILInstanceInitializers(ILGenerator il)
at Microsoft.JScript.Class.TranslateToCOMPlusClass()
at Microsoft.JScript.Class.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.Package.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.Block.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.ScriptBlock.TranslateToIL(ILGenerator il, Type rtype)
at Microsoft.JScript.ScriptBlock.TranslateToILClass(CompilerGlobals compilerGlobals, Boolean pushScope)
at Microsoft.JScript.VsaStaticCode.TranslateToIL()
at Microsoft.JScript.Vsa.VsaEngine.DoCompile()
at Microsoft.Vsa.BaseVsaEngine.Compile()
Viel Glück, wenn Sie das Problem mit einer solchen Meldung finden müssen.
JScript.NET hat einige Funktionen, die für einige Projekte interessant sein könnten, wie z.B. Prototyping (Hinzufügen neuer Eigenschaften und ich glaube auch Methoden zu einer bestehenden Instanz eines beliebigen Objekts), hat eine Art von Lamda-Funktionen bereits seit .NET 1.1 (vielleicht 1.0) usw. Aber um dieses völlig andere Verhalten zu erreichen, als es mit .NET 1.1 möglich war, mussten sie alles in Laufzeit-Helfer verpacken, JScript.NET hat eine eigene String-Klasse, die bei Bedarf in System.String hin und her konvertiert wird. Dasselbe gilt für Arrays, JScript hat seine eigene Implementierung und muss sie konvertieren, wenn eine Framework-Funktion mit einem Array als Parameter aufgerufen wird usw.
Ich habe so komische Dinge erlebt, dass eine Anfrage an die Datenbank zweimal ausgeführt wurde, wenn ich sie direkt als Parameter an eine Methode übergeben habe ( DoSomething(myRequest.Execute())
war das Ergebnis der Anfrage vom Typ System.String[][]
), aber das Ganze funktioniert einwandfrei, wenn ich das Ergebnis zuerst einer Variablen zuweise und es dann an die Methode übergebe, oder wenn ich versuche, ein Array mit System.Array.Sort(..)
wird sie einfach ignoriert und so weiter.
Ich habe das Gefühl, dass JScript.NET eine Fallstudie war, um zu beweisen, dass es auch möglich ist, Sprachen mit einer ganz anderen Philosophie zu implementieren, und dass Microsoft es aufgegeben hat, als sie merkten, dass der Ansatz nicht gut gewählt war. Aber sie haben die Lektion gelernt und mit PowerShell, das eine ähnliche Philosophie hat, hervorragende Arbeit geleistet.
Aber um es kurz zu machen: Verwenden Sie nicht JScript.NET, wenn Sie es nicht müssen, sondern eine moderne Sprache wie C# oder VB.NET, und wenn Sie Skriptfunktionen benötigen, empfehle ich CSScript.