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>