Discriminated-unions in C# So I really want to have something similar to discriminated unions in C#.

One way to do it is to use a visitor pattern, but it takes half a life to write all broilerplate code by hands.
There is another way that would allow me writing a bit less code, but it is based on delegates.

Consider the analogue of Options from F#:

public abstract class Optional&lt;TValue&gt;
{
    public abstract TResult Resolve&lt;TResult&gt;(Func&lt;TValue, TResult&gt; someHandler, Func&lt;String, TResult&gt; noneHandler);
}

public class Some&lt;TValue&gt; : Optional&lt;TValue&gt;
{
    public Some(TValue value)
    {
        this.Value = value;
    }
    public TValue Value { get; private set; }
    public override TResult Resolve&lt;TResult&gt;(Func&lt;TValue, TResult&gt; someHandler, Func&lt;String, TResult&gt; noneHandler)
    {
        return someHandler(this.Value);
    }
}

public class None&lt;TValue&gt; : Optional&lt;TValue&gt;
{
    public None(String message)
    {
        this.Message = message;
    }
    public String Message { get; private set; }
    public override TResult Resolve&lt;TResult&gt;(Func&lt;TValue, TResult&gt; someHandler, Func&lt;String, TResult&gt; noneHandler)
    {
        return noneHandler(this.Message);
    }
}

public class Demo {
    public Optional&lt;Uri&gt; ParseAbsoluteUri(String whateverUrl)
    {
        if (Uri.IsWellFormedUriString(whateverUrl, UriKind.Absolute))
        {
            var uri = new Uri(whateverUrl, UriKind.Absolute);
            return new Some&lt;Uri&gt;(uri);
        }
        else
        {
            return new None&lt;Uri&gt;("Given URL is not absolute.");
        }
    }
    public String ProcessUrl(String whateverUrl)
    {
        var uriOpt = this.ParseAbsoluteUri(whateverUrl);
        var result = uriOpt.Resolve(uri =&gt; "Hey, your URL \"" + uri + "\" looks nice!", message =&gt; "Sorry, the URI that you gave looks bad: " + message);
        return result;
    }
    public void Test()
    {
        Trace.WriteLine(this.ProcessUrl("http://google.com"));
        Trace.WriteLine(this.ProcessUrl("Not url at all"));

        /* output: 
            Hey, your URL "http://google.com/" looks nice!
            Sorry, the URI that you gave looks bad: Given URL is not absolute.
         */
    }
}



Each delegate is essentially a class that the C# compiler makes to wrap the pointer to a function. So with the excessive use of such approach will I hit any sort of problems? (Bloating the size of the assembly for example?)
Delegates aren't the fastest things in the galaxy, especially multicasts ones, this approach uses them heavily.
Making a call to a virtual method lessens (if not eliminates at all) a chance for JIT inlining.


So all in all I am a bit scared to go all the way this way due to performance concerns. I would like to know what you think of this.
This looks very well crafted. I don't know f# and I'm not really into functional programming, but I can enumerate everything I like about this code:


Type parameter names are descriptive: TValue and TResult are perfect.
The interface for Optional&lt;TValue&gt; is segregated; it's very focused and specialized, which makes it highly reusable... which is a nice feature for an abstract class.
Usage of this qualifier is consistent.


Well as I enumerated these points I did find a few minor nitpicks:


Usage of this qualifier is redundant.
Usage of String could be replaced with C# language alias string (but then again usage of String is beautifully consistent).


And as I enumerated these minor nitpicks I did find one tiny little thing that could be improved: the Message property in the derived types is only assigned through the constructor, using the private setter. I'd make it readonly and change the auto-property for a get-only property:

public None(String message)
{
    _message = message;
}

private readonly String _message;
public String Message { get { return _message; } }


...and this is where I'm clashing with this - I prefer prefixing private fields with an underscore and avoid this altogether, you might have it like this instead:

public None(String message)
{
    this.message = message;
}

private readonly String message;
public String Message { get { return this.message; } }