Using C#

Code snippets

While XSharper has basic primitives like expressions, or if/else, or while loop, these are often not sufficient. Instead of reinventing the wheel, it is very easy to embed C# code into the script.

<xsharper>
	<code>
		Console.WriteLine("Hello, world!")
	</code>
</xsharper>

Everything inside <code> is a single class, so local variables defined in one code block are not accessible in another.

It's also possible to mix & match too by inserting actions into C# code. And even add methods to the class written in C#.

<!-- CODE-MIX-AND-MATCH.XSH -->
<xsharper>
	<code>
		Console.WriteLine("This is a header!");
		<print>This is line #2</print>

		for (int i=0;5>i;++i)
		{
			c["x2"]=square(i);
			c.Write(i+"^2");
			<print>=${x2}</print>
		}

		<sub id="square">
			<param name="n" />
			<return>${=$n*$n}</return>
		</sub>
	</code>
</xsharper>

Some interesting notes:

  • there is a variable c, or Context, that can be used to access current script context, get/set variables etc.
  • for (int i=0;5>i;++i) construction, which is used to avoid the cumbersome &lt; instead of < sign. && is inconvenient for the same reason.

However, when inserting larger pieces of C# code, perhaps copy-pasted from somewhere, XML escaping becomes rather annoying. There are two possible solutions.

CDATA section:

<code><![CDATA[[
	for (int i=0; i<5;++i)
		c.WriteLine("i="+i);
]]></code>

or an XML processing instruction:

<?code
	for (int i=0; i<5;++i)
		c.WriteLine("i="+i);
?>

Which can be further shortened from <?code to <?_:

<?_
	for (int i=0; i<5;++i)
		c.WriteLine("i="+i);
?>

Headers

As everything inside <code> is inserted by XSharper into a class, it's not possible to define complete classes to be shared with different <code> actions, or define namespaces.

To insert code outside of any class or execution sequence, there is a <header> action, which may be also inserted as <?header or <?h processing instruction.

<!-- prints
	MD5('The quick brown fox jumps over the lazy dog.') = 'e4d909c290d0fb1ca068ffaddf22cbd0'
-->
<?h 
	using System.Security.Cryptography; 

	public static class Helper 
	{
		public static string md5 (byte[] data)
		{
			using (HashAlgorithm h=(HashAlgorithm)MD5.Create())
				return XS.Utils.ToHex(h.ComputeHash(data));
		}
	}
?>
<set str="The quick brown fox jumps over the lazy dog." />
<print value="MD5('${str}')='${=Helper.MD5(Encoding.ASCII.GetBytes($str))}'"/>

References

To add a reference to another assembly, there is a <reference> action. Assemblies may be referenced by name (using name attribute) or by location (using from attribute)

<reference name="System.Windows.Forms" />
<?h using WF= System.Windows.Forms; ?>
<eval>
	WF.MessageBox.Show("Hello, world");
</eval>

or a bit shorter:

<reference name="System.Windows.Forms" addUsing="true" />
<eval>
	MessageBox.Show("Hello, world");
</eval>