This feature has a full weight equivalent Autoclass
functionality, which is a built-in feature of the CS-Script engine.It
is implemented as an internal precompiler thus it can be easily
improved by developing your custom "autoclass precompiler" instead. See
Precompilers chapter for details.
Sometimes it is desirable to have
very light scripts with working code only and no code infrastructure. Fortunately, this can
be accomplished by extending CS-Script without changing it's core
implementation. And this has already been partially done in the earlier versions with the code.cs script (see Script Library). This script allows execution of the C# code statements from the command-line
without having any script file at all.
The current version of the CS-Script comes with CSSCodeProvider.dll assembly. It is an alternative compiler, which can handle C#, VB, JScript, C++ and C# (classless C#) syntax. This compiler makes decision which particular parser to engage at
run time on the base of the script file extension. The extension .ccs will always trigger the usage of the classless C# (CC#) parser.
The CC# parser is a very primitive parser, which analysis the code in order
to detect
if it is written in classless or standard C# syntax. If the
script code is a classless C# it is injected into an empty class declaration and
obtained code is executed, otherwise the script is executed as usual.
Every thing what can be achieved in standard C# can be done with classless C# too. As with standard C# scripts you can import other scripts from you code. The important
thing to remember, when doing this, is that compiler
automatically adds namespace and class to the imported script. Inserted namespace is the imported script file name without extension and the class name is normally "Script". Thus if
you import the following script (imp.ccs):
public static void Print(string text)
{
Console.WriteLine(text);
} |
t
he compiler will interpret it as following:
using System;
namespace imp
{
public partial class Script
{
public static void Print(string text)
{
Console.WriteLine(text);
}
}
} |
So if you need to import imp.ccs file it would need to be done this way (impTest.ccs):
//css_import imp.ccs;
auto_imp.Script.Print("test"); |
Note:
- Any .ccs file can import both .cs and .ccs scripts, however .cs can do only another .cs files.
-
Remember that usage of namespaces can help to avoid any naming collisions.
- Note
that by default the auto-generated namespace for the imported classless
script is a name of the script file (without extension) with
prefix "auto_". This is required to avoid potential problems when the
script file name starcts with a number (in C# namespace must start
with an alphabetic character).
- You can use ccs2cs.cs (Script Library) script to do conversion of any CC# script to the standard C# script.
You can control how class infrastructure is generated by using
//css_classless
directive, which allows specifying class name (including namespace) for
class to be generated. You may need to use this feature when
hosting calssless script.
//css_classless MyNamespace.MyClass;
static public void SayHello(string greeting) { Console.WriteLine(greeting); } |
The script above will be interpreted at runtime as following:
namespace MyNamespace { public partial class MyClass { static public void SayHello(string greeting) { Console.WriteLine(greeting); } } } |
Limitations
Classless C# syntax implies some
restrictions and limitations. Thus any file which contains classless C# must
consist of the following parts:
- Optional header
contains C# and CS-Script directives (e.g. using System.IO; //css_reference CSScriptLibrary.dll;)
- Body
contains a free standing C# code without any class declarations
- Optional footer
contains additional class declarations and method definitions
Because it is not possible to predict
future changes in the standard C# syntax or even due to the
implementation limitations it is possible that CC# parser may produce
incorrect outcome. For such cases special CC# code markers can be used to insure correct parsing. Such markers are used to indicate the start and the end of the CC# code Body part and they are:
//css_begin;
//css_end;
The usage of these markers can be illustrated with the following code:
using System;
//css_begin;
Print("test");
//css_end;
static void Print(string text)
{
Console.WriteLine(text);
} |
Examples
This is an example of the script, which sets a Read-Only attribute to all files from the current directory .
using System.IO;
using System.Windows.Forms;
string msg = "Do you want to make all files in "
+ Environment.CurrentDirectory + " Read-Only?";
if (DialogResult.Yes == MessageBox.Show(msg, "CS-Script", MessageBoxButtons.YesNo))
foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
File.SetAttributes(file, FileAttributes.ReadOnly); |
This is a different edition of the same script. Now the classless C# code contains method definition.
using System.IO;
using System.Windows.Forms;
string dir = Environment.CurrentDirectory;
string msg = "Do you want to make all files in "+dir+" Read-Only?";
if (DialogResult.Yes == MessageBox.Show(msg, "CS-Script", MessageBoxButtons.YesNo))
SetReadOnly(dir);
static void SetReadOnly(string dir)
{
foreach (string file in Directory.GetFiles(dir))
File.SetAttributes(file, FileAttributes.ReadOnly);
} |
This
is an example of the script (the simplest possible), which prints the names of all .exe files
from the current directory. This script does not have any using directives at all (using System; is always assumed for all classless scripts).
foreach (string file in System.IO.Directory.GetFiles(Environment.CurrentDirectory, "*.exe"))
Console.WriteLine(file); |
This
is another version of the script above, which illustrates the usage of classes in the classless scripts.
new Executables().Print();
class Executables
{
public void Print()
{
var files = System.IO.Directory.GetFiles(Environment.CurrentDirectory, "*.exe");
foreach (string file in files)
Console.WriteLine(file);
}
} |
See Also
Alternative
compilers |
Script Library |
Importing scripts