The gsharp command is a GUI version of the C# interpreter that uses Gtk# and provides an area to attach widgets as well. This version can be attached to other Gtk# applications in a safe way as it injects itself into the main loop of a Gtk# application, avoiding any problems arising from the multi-threaded nature of injecting itself into a target process.
This version allows a number of scripts to be specified in the command line.
$ csharp Mono C# Shell, type "help;" for help Enter statements below. csharp>
A number of namespaces are pre-defined with C# these include System, System.Linq, System.Collections and System.Collections.Generic. Unlike the compiled mode, it is possible to add new using statements as you type code, for example:
csharp> new XmlDocument (); <interactive>(1,6): error CS0246: The type or namespace name `XmlDocument' could not be found. Are you missing a using directive or an assembly reference? csharp> using System.Xml; csharp> new XmlDocument (); System.Xml.XmlDocument
Every time a command is typed, the scope of that command is one of a class that derives from the class Mono.CSharp.InteractiveBase. This class defines a number of static properties and methods. To display a list of available commands access the `help' property:
csharp> help; "Static methods: LoadPackage (pkg); - Loads the given Package (like -pkg:FILE) [...] ShowVars (); - Shows defined local variables. ShowUsing (); - Show active using decltions. help; " csharp>
When expressions are entered, the C# shell will display the result of executing the expression:
csharp> Math.Sin (Math.PI/4); 
0.707106781186547
csharp> 1+1;
2
csharp> "Hello, world".IndexOf (',');
5
The C# shell uses the ToString() method on the returned object to display the object, this sometimes can be limiting since objects that do not override the ToString() method will get the default behavior from System.Object which is merely to display their type name:
csharp> var a = new XmlDocument (); csharp> a; System.Xml.Document csharp> csharp> a.Name; "#document" csharp>
A few datatypes are handled specially by the C# interactive shell like arrays, System.Collections.Hashtable, objects that implement System.Collections.IEnumerable and IDictionary and are rendered specially instead of just using ToString ():
csharp> var pages = new Hashtable () { 
      >  { "Mono",    "http://www.mono-project.com/" },
      >  { "Linux",   "http://kernel.org" } };
csharp> pages;
{{ "Mono", "http://www.mono-project.com/" }, { "Linux", "http://kernel.org" }}
It is possible to use LINQ directly in the C# interactive shell since the System.Linq namespace has been imported at startup. The following sample gets a list of all the files that have not been accessed in a week from /tmp:
csharp> using System.IO;
csharp> var last_week = DateTime.Now - TimeSpan.FromDays (7);
csharp> var old_files = from f in Directory.GetFiles ("/tmp") 
      >   let fi = new FileInfo (f) 
      >   where fi.LastAccessTime < LastWeek select f;
csharp>
You can of course print the results in a single statement as well:
csharp> using System.IO;
csharp> var last_week = DateTime.Now - TimeSpan.FromDays (7);
csharp> from f in Directory.GetFiles ("/tmp") 
      >   let fi = new FileInfo (f) 
      >   where fi.LastAccessTime < last_week select f;
[...]
csharp>
LINQ and its functional foundation produce on-demand code for IEnumerable return values. For instance, the return value from a using `from' is an IEnumerable that is evaluated on demand. The automatic rendering of IEnumerables on the command line will trigger the IEnumerable pipeline to execute at that point instead of having its execution delayed until a later point.
If you want to avoid having the IEnumerable rendered at this point, simply assign the value to a variable.
Unlike compiled C#, the type of a variable can be changed if a new declaration is entered, for example:
csharp> var a = 1; csharp> a.GetType (); System.Int32 csharp> var a = "Hello"; csharp> a.GetType (); System.String csharp> ShowVars (); string a = "Hello"
In the case that an expression or a statement is not completed in a single line, a continuation prompt is displayed, for example:
csharp> var protocols = new string [] {
      >    "ftp",
      >    "http",
      >    "gopher" 
      > };
csharp> protocols;
{ "ftp", "http", "gopher" }
Long running computations can be interrupted by using the Control-C sequence:
csharp> var done = false;
csharp> while (!done) { }
Interrupted!
System.Threading.ThreadAbortException: Thread was being aborted
  at Class1.Host (System.Object& $retval) [0x00000] 
  at Mono.CSharp.InteractiveShell.ExecuteBlock (Mono.CSharp.Class host, Mono.CSharp.Undo undo) [0x00000] 
csharp>
The command set is similar to many other applications (cursor keys) and incorporates some of the Emacs commands for editing as well as a history mechanism to
The following keyboard input is supported:
csharp> Time (() => { for (int i = 0; i < 5; i++) Console.WriteLine (i);});
0
1
2
3
4
00:00:00.0043230
csharp>
The return value is a TimeSpan, that you can store in a variable for benchmarking purposes.
C# script files are files that have the extension .cs and they should only contain statements and expressions, they can not contain full class definitions (at least not as of Mono 2.0). Full class definitions should be compiled into dlls and stored in that directory.
The home page for the Mono C# compiler is at http://www.mono-project.com/CSharp_Compiler information about the interactive mode for C# is available in http://mono-project.com/CsharpRepl