I wrote up how I'd do this in scala, just to compare and contrast
val shape: Option[Shape] = ???
shape.map {
case Square(0) | Circle(0) => 0
case Triangle(b, h) if b == 0 || h == 0 => 0
case Rectangle(l, h) if l == 0 || h == 0 => 0
case Square(side) => side * side
case Circle(radius) => radius * radius * math.Pi
case Triangle(base, height) => base * height / 2
case Rectangle(length, height) => length * height
}
what I noticed
* scala doesn't have a way for cases to fall through, so the first cases have to each declare that the result is 0. it would be cool if we could use something in place of '=>' to make the case fall through.
* C# doesn't have structural matching, so the 'when' keyword is used more often.
* scala's pattern matching is exhaustive so if we assume the shapes are in a sealed type hierarchy then we don't need a default case.
* it's idiomatic to use 'Option' instead of null in scala, but there are lots of libraries in c# that offer option monads, so it's more a point of what's idiomatic than what's possible.