Is it possible to create a C# record with a private constructor?

Viewed 1807

Hello,

I´m trying to rebuild a discriminated union type in C#.
I always created them with classes like this:

public abstract class Result
{
    private Result() { }

    public sealed class Ok : Result
    {
        public Ok(object result)    // don´t worry about object - it´s a sample
            => Result = result;
        
        public object Result { get; }
    }

    public sealed class Error : Result
    {
        public Error(string message)
            => Message = message;

        public string Message { get; }
    }
}

The problem is that is sooooo much boilerplate code when comparing to F#:

type Result =
    | Ok of result : object
    | Error of message : string

So I tried to rebuild the type with the help of C#9 records.

public abstract record Result
{
    public sealed record Ok(object result) : Result;
    public sealed record Error(string message) : Result;
}

Now it is way less code but now there is the problem that anyone can make new implementations of Result because the record has a public constructor.

Dose anyone have an idea how to restrict the implementations of the root record type?

Thanks for your help and your ideas!

1 Answers

I solved it with the help of your comments and this other stackoverflow article.

namespace System.Runtime.CompilerServices
{
    internal static class IsExternalInit { }
}

namespace RZL.Core.Abstractions.DMS
{
    public abstract record Result
    {
        private Result() { }

        public sealed record Ok(object result) : Result;
        public sealed record Error(string message) : Result;
    }
}
Related