A C# library to write functional code – Part III – Records

Other posts in the series:

  • Part I – Background
  • Part II – Tuples
  • Part III – Records

  • Part IV – Type Unions

  • Part V – The Match operator

  • Now that we know what Tuples are, we can start talking about Record, as they use a derivative of Tuples under the cover. But first, what is a record?

    Well, in C# parlance a Record is a sort of immutable value object. I talked at length about these fellows in this series of blog posts. In functional parlance, a Record is a Tuple that lets you access its items by name.

    You code Records like this:

        public class Order: Record<string, int> {

    public Order(string item, int qty): base(item,qty) {}

    public string Item { get { return state.Item1;}}
    public int Quantity { get { return state.Item2; } }

    public class Customer: Record<string, IEnumerable<Order>> {

    public Customer(string name, IEnumerable<Order> orders) : base(name, orders) { }

    public string Name { get { return state.Item1; } }
    public IEnumerable<Order> Orders { get { return state.Item2; } }

    You need to do three things:

    1. Inherit from a generic Record class specifying the types of the properties as parameters

    2. Add a constructor that calls back to the Record constructor

    3. Add getters to retrieve the values of the properties (no setters as it is immutable)

    This may seem like plenty of work, but in return you get structural equality. Coding that by hand every time you use a record would be a royal pain. You lose control of the base class, but that is often not a problem as in functional-land you more often use type unions than inheritance.

    How is it implemented?

    First of all it is an abstract class with as many generic parameters as properties that you need in your Record. Let’s use two as an example.

        public abstract class Record<T1, T2> {

    This abstract class has a field of type STuple:

            protected readonly STuple<T1, T2> state;

    What is a STuple? Well it is exactly the same as the Tuple described in Part II, but coded as a struct instead of a class. The reason to use a struct is to not allocate an additional object on the stack. This allows this solution to be as ‘performant’ as simply having coded the fields on the class itself. Or at least I think so …

    The Record class also has a constructor that simply initialize the STuple:

            public Record(T1 t1, T2 t2) { state = F.STuple(t1, t2); }
            internal static STuple<T1, T2> STuple<T1, T2>(T1 t1, T2 t2) {

    return new STuple<T1, T2>(t1, t2);

    The Equals method is very much the same as the Tuple’s one, just delegating to the same DSEqual function that checks equality for Tuples.

            public override bool Equals(object right) {


    if (object.ReferenceEquals(this, right))
    return true;

    if (this.GetType() != right.GetType())
    return false;

    var rightT = right as Record<T1, T2>;

    return F.DSEquals(this.state, rightT.state);

    That’s it. Not too difficult as most of the implementation is based on the Tuple’s code. Next post will hopefully be more interesting. It is about Type Unions.

    13 thoughts on “A C# library to write functional code – Part III – Records

    1. By the way, there’s another reason your hash-code algorithm is unwise: Assuming the component hash-codes are uniformly distributed over the integers from 0 to 2^32-1 (thus interpreting the signed integers as unsigned integers here, for simplicity), your will not be:  a binary or never lowers the number of "on" bits; each bit of your result hash code has only a 25% chance to be off – which lowers the entropy of the overall hash code to be around 26 bits, as opposed to 32 bits.
      Finally, tuples of tuples will hash particularly badly; and so will tuples with higher than 2-arity.

    2. Wow, a little more and we’ll finally have the easy-to-use record construct of Pascal in the 1980s.  Just declare a Record type and you’re set.  I have (seriously) often wished for this in C# instead of cumbersome, separate struct or class def’s.

    3. This’s a really excellent introduction. I think I begin to know what the functional code is after reading your posts and code. But I have some questions about this:
      For the GetHashCode(), why don’t you try "xor" other than "or"? I think "xor" will get a better job than the "or"~
      For something about all the code, and I found TypeUnion<T> is really useless! Since I’ll never have the change to use a member union!

    4. Previous posts: Part I – Background Part II – Tuples Now that we know what Tuples are, we can start talking about Record, as they use a derivative of Tuples under the cover. But first, what is a record? Well, in C# parlance a Record is a sort of immutabl

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s