I worked for years in .NET back in the 1.1 to 2.0 days, then moved off to Java, then Python, and finally Scala. However, now I am back to doing some .NET again after being away from it for almost four years. I work in Scala on a daily basis and when I heard I would be doing .NET again I was a bit sad, since I enjoy the syntax in Scala so much. However, since my last experience with .NET was in the 2.0 days, things have changed for the better. With .NET 4.0 a lot of functional style syntax has been incorporated into the language (They have done the opposite of Java and continued to evolve the language). So as I have been working with .NET 4.0, everyday I find myself thinking “If only I had Scala, I could write this in one line”. This has prompted me to actually look for equivalents, and it turns out there are a great deal of them! (Hint: LINQ is a great place to start!)
The funny thing is I am the only person in my office who is willing to work on both sides. I just want to use the best tool for the job, or the tool that makes the most business sense given what needs to be done, the resources available, and what code already exists. So I thought I would write up a few quick Scala and C# examples showing the equivalent syntax to help get you started.
Also, as a note, if you are using C# 4.0, I highly recommend using the re-factoring tool Resharper made by JetBrains who make IntelliJ. This tool has been very handy, often I will write a line or two of code in the old way in C#, and it will highlight and suggest the newer cleaner syntax, and in most cases will actually translate what I have written into the new style (e.g, if you write foreach() {} to loop through a list it will rewrite it as myList.ForEach() etc.). That is a trivial example, but for more complex statements it is a great teaching tool.
ForEach on a list
Let’s create a list of strings and loop through them, printing each string to the console.
Scala:
val someStrings = List("one","two","three") someStrings.foreach(x => println(x))
C#:
var someStrings = new List<string> { "one", "two", "three" }; someStrings.ForEach(x => Console.WriteLine(x));
Scala has “_” but C# has Method Groups
In the above example any Scala developer would say “But you can write that example with the much cleaner syntax using the underscore”. Yes, that is true I totally agree. In fact I was annoyed that I did not have an equivalent until my ReSharper prompted me in Visual Studio to rewrite the above C# statement using Method Groups. So here they are:
Scala:
val someStrings = List("one","two","three") someStrings.foreach(println(_))
C#:
var someStrings = new List<string> { "one", "two", "three" }; someStrings.ForEach(Console.WriteLine);
So in C#, since the parameter being passed is a string, and the method takes a string, there is no need to explicitly write it out. This is also very handy when using LINQexpressions, such as “Select”.
Tuples
I was working on a piece of code recently in C# and really wished I could use a Tuple in C#. Well, once again I was surprised to find out it was available:
Scala:
val myTuple = ("Hello", 123) println(myTuple._1) println(myTuple._2)
C#:
var myTuple = Tuple.Create("Hello", 123); Console.WriteLine(myTuple.Item1); Console.WriteLine(myTuple.Item2);
FoldLeft equivalent is Aggregate
Let’s use the basic introduction to FoldLeft example and calculate the sum of a list of numbers.
Scala:
val numbers = List(1,2,3,4,5) val total = numbers.foldLeft(0)((result,current) => result + current) println(total) //Of course any Scala developer would lean towards the Syntax which I have not found an equivalent for in C# val total2 = numbers.foldLeft(0)(_+_) println(total2)
C#:
var numbers = new List<int> {1, 2, 3, 4, 5}; var total = numbers.Aggregate(0, (result, current) => result + current); Console.WriteLine(total);
As you can see the syntax for the Aggregate function is very similar. In fact it took me a while to figure out what method call in C# was the equivalent to a foldLeft just because of the name. Also just as a note their are two types of Aggregate, “Simple” is where you do not need to specify an initial value, while “Seed” is where you do specify an initial value, so the example above is a “Seed” since we are starting our sum with an initial value of 0.
Yes, they both have the “sum” function as well
I know that is a trivial foldLeft and aggregate example, so just to be clear, yes they both have “sum” as well.
Scala:
val numbers = List(1,2,3,4,5) val total = numbers.sum println(total)
C#:
var numbers = new List<int> {1, 2, 3, 4, 5}; var total = numbers.Sum(); Console.WriteLine(total);
Filter equivalent is FindAll
Scala:
val numbers = List(1,2,3,4,5) val numbersSubset = numbers.filter(x => x > 2) println(numbersSubset.length)
C#:
var numbers = new List<int> {1, 2, 3, 4, 5}; var numbersSubset = numbers.FindAll(x => x > 2); Console.WriteLine(numbersSubset.Count);
Let’s combine two list operations in one statement
Scala – filter followed by forEach
val numbers = List(1,2,3,4,5) numbers.filter(x => x > 2).foreach(println(_))
C# – FindAll followed by a ForEach
var numbers = new List<int> {1, 2, 3, 4, 5}; numbers.FindAll(x => x > 2).ForEach(Console.WriteLine);
Constructing a class with named parameters
Yes, I realize these classes are not equivalent, however, they are just for the examples to use below.
Scala:
case class Person(name: String) val john = new Person(name = "John Smtih")
C#:
class Person { public string name { get; set; } } var john = new Person { name = "John Smith" };
Construct a new list adding a new Person object to it at the same time
Scala:
case class Person(name: String) val johns = List(new Person(name = "John Smith"))
C#:
class Person { public string name { get; set; } } var johns = new List<Person> { new Person { name = "John Smith" } };
Converting a list of objects of one type into another
Now, just as an example of something a little more fun, let’s take the list of “Person” objects we created in the previous example and convert them into a list of “Employee” objects.
Scala – For Scala we will use foldLeft to accomplish this task
case class Employee(name: String) val employees = johns.foldLeft(List[Employee]())((result,current) => Employee(current.name) :: result) employees.foreach(x => println(x.name))
C# – For C# you could use Aggregate, but instead let’s try using the LINQ expression “Select”
class Employee { public string name { get; set; } } var employees = johns.Select(person => new Employee { name = person.name }).ToList(); employees.ForEach(x => Console.WriteLine(x.name));
That’s all for now. As a side note I highly recommend getting familiar with LINQ, it is very useful. The site 101 LINQ Samples in C# is a great place to get started.