Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Fareez Ahamed
Fareez Ahamed

Posted on • Originally published atfareez.info

     

Emulating Discriminated Unions in C# using Records

Discriminated Union / Sum Type is one of the common features found amoung strong typed functional languages like F#, Haskell etc. Ever since I started using them in F#, I can't stop wondering why such an useful feature is not available on the popular languages. C# has been adding a lot of functional features over the last few years. So, we are going to achieve something close to that in C# using Records and Inheritance.

In F#, we can create aDiscriminated Union forShape as shown below.

type Shape = Circle of int            | Square of int            | Rectangle of int * int            | Triangle of int * int * int            | Line of int
Enter fullscreen modeExit fullscreen mode

Discriminated Unions alone cannot be beneficial without powerfulPattern Matching constructs built into the language. In the case of F#, calculating area for any shape is easy as writing a function with Pattern Matching.

let getArea s =     match s with    | Circle(r) -> Math.PI * float(r) * float(r)    | Square(x) -> float(x*x)    | Rectangle(l, b) -> float(l*b)    | Triangle(a, b, c)         when a = b && b = c             -> Math.Pow(float(a), 2.0) * Math.Sqrt(3.0)/4.0    | Triangle(a, b, c)         when Math.Pow(float(c), 2.0) =             Math.Pow(float(a), 2.0) + Math.Pow(float(b), 2.0)             -> float(a * b) / 2.0    | _ -> 0.0
Enter fullscreen modeExit fullscreen mode

Now lets see how we can express this in terms of Records in C#.

Records are introduced in C# 9.0 which are special classes with value equality
and simpler syntax. It takes a constructor with parameters and all the parameters mentioned in the constructor are automatically promoted into Properties with{init; get;}. Records are immutable and compared by values by default, just like any F# type.(However, there are some differences like deep equality is not guaranteed when reference types are used within Records which we are not going to give attention now.)

publicrecordShape{};publicrecordCircle(intRadius):Shape;publicrecordSquare(intSide):Shape;publicrecordRectangle(intWidth,intHeight):Shape;publicrecordTriangle(intA,intB,intC):Shape;publicrecordLine(intLength):Shape;
Enter fullscreen modeExit fullscreen mode

So here we create an emptyShape record which is being inherited by all the other shapes but with different set of parameters. Inheritance is the only relationship among these types which enables us to pass different shape objects likeCircle orSquare in the place ofShape. As I said earlier,Discriminated Unions are not useful on its own without Pattern Matching and C# has been adding good Pattern Matching support over last few versions. This allows us to compare type of the Record and evaluate an expression based on that.

So thegetArea function would like the one below in C# 9.0.

staticdoubleArea(Shapes)=>sswitch{Circlec=>Math.PI*c.Radius*c.Radius,Squaresquare=>square.Side*square.Side,Rectangler=>r.Width*r.Height,Trianglet// Equilateral TrianglewhenMath.Pow(t.C,2)==Math.Pow(t.A,2)+Math.Pow(t.B,2)=>t.A*t.B/2,Trianglet// Right angled Trianglewhent.A==t.B&&t.B==t.C=>Math.Pow(t.A,2)*(Math.Sqrt(3)/4),Lineor_=>0,};
Enter fullscreen modeExit fullscreen mode

It is pretty close to the F# version of the code. Honestly I didn't expect C# would catch up with such good Pattern Matching so soon. But it's not quite common yet to see C# code similar to this as it will take time for the developers to adopt to the new way of thinking to solving problems.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Full Stack Web Developer with React, Laravel, Go, .Net Core
  • Location
    Chennai, India
  • Work
    Senior Software Engineer at EPAM Systems
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp