- Part 1: Differences in similarities
- Part 2: A brand new world
Delegate: Method as a first-class citizen
A delegate is a special type that defines a method signature. Delegates are like C function pointers with type safety that allow methods to be passed as parameters and stored in a structure or a class.
// Declaration of a delegate type
delegate string StringOperation(string str);
public class Delegates
{
public static string Reverse(string str) // doesn't support full unicode charset
{
char[] arr = str.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
public static void Main(string[] args)
{
StringOperation normalizeOp;
// Creation of a delegate instance
normalizeOp = Delegates.Reverse;
Console.WriteLine(normalizeOp("abcd")); // dcba
// Instantiate the delegate using an anonymous method.
normalizeOp = delegate(String str) { return str.Trim(); };
Console.WriteLine(normalizeOp(" abcd ")); // abcd
}
}
To mimic this feature in Java, the developer will have to create a class implementation (generally an anonymous inner class) where one method performs the action.
interface StringOperation
{
String invoke(String str);
}
public class Delegates
{
public static String reverse(String str)
{
return new StringBuffer(str).reverse().toString();
}
public static void main(String[] args)
{
StringOperation normalizeOp;
normalizeOp = new StringOperation(){
public String invoke(String str)
{
return Delegates.reverse(str);
}
};
System.out.println(normalizeOp.invoke("abcd")); // dcba
normalizeOp = new StringOperation(){
public String invoke(String str)
{
return str.trim();
}
};
System.out.println(normalizeOp.invoke(" abcd ")); // abcd
}
}
The ability to refer to a method as a variable or as a parameter makes delegates ideal for a lot of usage, delegates are used everywhere in C#, as event handlers, thread actions, callbacks in asynchronous programming, in LINQ…
Event
In a GUI environment, any number of controls can raise an event (button click, menu selection, completion of a file transfer). Other classes will be interested in responding to these events but the publisher of the event is not interested by how classes receiving the event will respond. C# provide a specific syntax to enable event-driven programming implementing the publish/subscribe pattern.
class Button
{
public delegate void Action();
public event Action Click;
public void PerformClick()
{
OnClick();
}
private void OnClick()
{
if (Click != null)
{
Click();
}
}
}
class Program
{
static void PerformAction()
{
Console.WriteLine("Work!");
}
public static void Main()
{
Button button = new Button();
// Subscribe to the event
button.Click += PerformAction;
button.PerformClick(); // Work!
// Unsubscribe
button.Click -= PerformAction;
button.PerformClick(); // Nothing
}
}
In Java, there is no general mechanism for event handling, instead events are manually implemented with the observer pattern: anonymous inner classes are commonly used to implement the listener, allowing the developer to define the body of the class and create an instance of it in a single point in the code.
public interface ClickListener extends EventListener
{
public void click();
}
public class Button
{
protected EventListenerList listenerList = new EventListenerList();
public void addMyEventListener(ClickListener listener)
{
listenerList.add(ClickListener.class, listener);
}
public void removeMyEventListener(ClickListener listener)
{
listenerList.remove(ClickListener.class, listener);
}
public void performClick()
{
onClick();
}
void onClick()
{
Object[] listeners = listenerList.getListenerList();
for (int i=0; i<listeners.length; i+=2)
{
if (listeners[i]==ClickListener.class)
{
((ClickListener)listeners[i+1]).click();
}
}
}
}
public class Program
{
public static void main(String[] args)
{
Button button = new Button();
button.addMyEventListener(new ClickListener() {
public void click(EventArgs evt)
{
System.out.println("Work!");
}
});
button.performClick();
}
}
Lambda Expression: Delegate on steroids
A lambda expression is an anonymous function that can be used to create delegates. Syntacticly it is composed of three parts: an input parameters list, the lambda operator =>, and a method body. Thanks to type inference, you often do not have to specify a type for the input parameters: the compiler can infer the type based on the body and the underlying delegate type.
delegate bool Assertion(int value); // Equivalent to (int x) => x == 42; Assertion isUniverseAnswer = x => x == 42; isUniverseAnswer(42); // true
One of the most important features of Lambda Expressions (and anonymous methods) is that they execute in the context of their declaration. Therefore, they can use the values of variables defined in that context.
List<User> FindAllYoungerThan(List<User> users, int limit)
{
// The lambda expression uses the outer variable "limit"
return users.FindAll(user => user.Age < limit);
}
Lambda expressions can be used to implement closures. Closures can be defined as functions that capture the state of the environment that is in scope where they are declared.
delegate void Action();
static Action CreateAction()
{
int counter = 0;
// Returns a delegate, the action is not executed here.
return () => Console.WriteLine("counter={0}", counter++);
}
void Main()
{
Action action = CreateAction();
action(); // counter=0
action(); // counter=1
}
LINQ’s awakening
LINQ (Language-Integrated Query) is a set of technologies based on the integration of query capabilities directly into C#. With LINQ, queries are a first-class language construct.
IEnumerable<int> query =
from user in users
select user.Age;
Query expressions are written in a declarative query syntax allowing filtering, ordering, and grouping operations. The same query expression could be used to query and transform data in from various sources: databases, datasets, XML documents, and collections. A single query can retrieve data from a SQL database, and produce an XML stream as output. The execution of the query is deferred until the result is requested. Deferred execution can greatly improve performance when manipulating large data collections with a series of chained queries or manipulations.
// 1. DataSource
int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
IEnumerable<int> numQuery = from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num); // 0 2 4 6
}
There is no magic behind LINQ: at compile time, query expressions are converted to standard method calls using query operators.
IEnumerable<int> querySyntax =
from user in users
select user.Age;
IEnumerable<int> methodSyntax = users.Select(user => user.Age);
No more StringUtils with Extension method
It is rather common to have classes full of utility methods that mostly enhance the functionalities of some other classes (StringUtils, ArrayUtils…)
Extension methods enable you to “add” methods to existing types without creating a new derived one or modifying the original. They are called as if they were instance methods on the extended type. The extension methods will hang on the type, so they will be easier to find with completion than an Util class.
string reversed = "Example".Reverse();
reversed = StringUtils.Reverse("Example")
Extension methods are used for LINQ to add standard query operators on existing IEnumerable types (Select, Where, GroupBy, OrderBy, Average…).
Pass by reference
In Java, arguments to a method are passed by value; a method operates on copies of the items passed to it instead of on the actual items: a copy of the value for primitive type and a copy of the reference for objects. Because of that simple things like swapping two numbers in a method are not easily doable in Java (must use a wrapper or some arithmetic).
By default, it works the same way in C# but it is possible to specify that the arguments of a method must be pass by reference. This is particularly useful when you want to create a method that returns more than one object.
A common pattern in the .NET framework is the TryXXX pattern. For example methods int Int32.Parse(string) and bool Int32.TryParse(string, out int) use this pattern, Int32.Parse is used to convert a string to an integer. The TryParse method is like the Parse method, except that TryParse does not throw an exception if the conversion fails. It eliminates the need to use exception handling in case the string cannot be successfully parsed.
// Using Parse method, with exception handling
int quantity;
try
{
quantity = int.Parse(input);
}
catch (FormatException)
{
quantity = 0;
}
// Using TryParse
int quantity;
if (!Int32.TryParse(txtQuantity.Text, out quantity))
{
quantity = 0;
}
This feature could also be used to improve performance when dealing with value type. When a value type is passed to a method its value is copied, if the value type is large (e.g. a 4×4 matrix includes 16 floats) it is better to pass a reference of the value type instead of a copy of it.
Matrix view = ...; Matrix projection = ...; Matrix viewProjection; Matrix.Multiply(view, projection, out viewProjection); // viewProjection = view * projection;
Partial type
.NET is big into automatic code generation: Visual Studio uses this for Windows Forms, Web service wrapper code creation. To facilitate the usage of generated code it is possible to split the definition of a class, a struct, an interface or a method over two or more source files. Each source file contains a section of the type or method definition, and all parts are combined when the application is compiled. That way one part of the type is edited by the code generator while the other part could be edited by the developer without the risk of the generator overwriting that code later.
// In file A
partial class HumptyDumpty
{
private string name = "Humpty Dumpty";
public void Rhyme()
{
Sat();
Fall();
TryPutTogether();
}
public void TryPutTogether()
{
string putTogether = @"All the king's horses and all the king's men
Couldn't put Humpty together again.";
Console.WriteLine(putTogether);
}
}
// In file B
partial class HumptyDumpty
{
void Sat()
{
Console.WriteLine("{0} sat on a wall,", name);
}
void Fall()
{
Console.WriteLine("{0} had a great fall.", name);
}
}
One useful usage is unit testing: the set of unit tests for a class is often much larger than the class implementation itself; the tests could be split into chunks using partial types. That way it is easier to work with the test suite but all the tests could still be run in one session (it is still a single test class).
Is that all?
Dynamic
Since version 4, C# provides a dynamic type. The main point is interoperability with COM API (Office API for example) and dynamic language such as IronPython or IronRuby (Python and Ruby running on the CLR). This feature will not be used by many developers in their day-to-day coding, but it can be useful and the cleaner way in some situation.
Example of C# code calling a python method through dynamic and IronPython.
ScriptRuntime py = Python.CreateRuntime();
dynamic random = py.UseFile("random.py");
int[] items = new int[]{0,1,2,3,4,5};
random.shuffle(items);
Null-coalescing operator
The null-coalescing operator ?? is used to define a default value. It is like a conditional binary operator tweaked for null value.
string address = user.BillingAddress ??
user.ShippingAddress ??
user.ContactAddress;
// Equivalent to:
string address = user.BillingAddress;
if (address == null)
{
address = user.ShippingAddress;
if (address == null)
{
address = user.ContactAddress;
}
}
Automatic Resource Management
The using keyword provides an easy way to manage resource by handling resource disposal automatically.
string line = String.Empty;
StreamReader reader;
try
{
reader = new StreamReader("file.txt"));
line = reader.ReadLine();
}
finally
{
if (reader != null)
reader.Dispose();
}
This sample which uses the using keyword is equivalent to the previous one.
string line = String.Empty;
using (StreamReader reader = new StreamReader("file.txt"))
{
line = reader.ReadLine();
}
Console.WriteLine(line);
Automatic resource management will be introduced in Java 7 as well (through java.lang.AutoCloseable interface).
try ( FileInputStream in = new FileInputStream("input.txt");
FileOutputStream out = new FileOutputStream("output.txt"))
{
int c;
while((c=in.read()) != -1 )
out.write();
}
And more
- Easy lazy iterator with
yield - Nullable type
- Unsafe code
- Conditional compilation
- …
It’s a wrap!
In this post I have showed C# features that differentiate the language from Java and which make C# a broader language with functional and dynamic pieces, with the objective of improving the expressiveness of the language.
In the following post I am going to describe the platform and infrastructure: framework, ide, build tool, continuous integration server…

Pingback: Why Java folks should look forward to Scala | /var/log/mind
Pingback: Why Java folks should stop looking down on C# [3/4] The ecosystem