Functional pattern matching in C#
In your Match class, I would mark the two private dictionaries as readonly to signify intent and keep them from being assigned to accidentally anywhere else:

private readonly Dictionary&lt;Type, Delegate&gt; funcs =
    new Dictionary&lt;Type, Delegate&gt;();

private readonly Dictionary&lt;TIn, TReturn&gt; values =
    new Dictionary&lt;TIn, TReturn&gt;();


Secondly, I'd design to interfaces and make them IDictionaries as good OO practice:

private readonly IDictionary&lt;Type, Delegate&gt; funcs =
    new Dictionary&lt;Type, Delegate&gt;();

private readonly IDictionary&lt;TIn, TReturn&gt; values =
    new Dictionary&lt;TIn, TReturn&gt;();


In your example classes, you should forego public member data and use properties accessing backing fields (also marked readonly):

abstract class Expression
{
    private readonly double _Value;

    protected Expression(double value)
    {
        this._Value = value;
    }

    public double Value
    {
        get
        {
            return this._Value;
        }
    }
}

abstract class BinaryExpression : Expression
{
    private readonly Expression _Left;

    private readonly Expression _Right;

    public BinaryExpression(Expression left, Expression right) : base(default(double))
    {
        this._Left = left;
        this._Right = right;
    }

    public Expression Left
    {
        get
        {
            return this._Left;
        }
    }

    public Expression Right
    {
        get
        {
            return this._Right;
        }
    }
}

class Add : BinaryExpression
{
    public Add(Expression left, Expression right) : base(left, right)
    {
    }
}

class Mul : BinaryExpression
{
    public Mul(Expression left, Expression right) : base(left, right)
    {
    }
}

class Num : Expression
{
    public Num(double x) : base(x)
    {
    }
}