Home > .NET CLR, .NET Framework, C#, Cocoa Libraries, Runtime > Objective-C and C#: Brothers From Another Mother

Objective-C and C#: Brothers From Another Mother

My colleague Paul Irwin just posted an article called Translating Objective-C to C# – Part 1 of n. I think it’s an excellent synopsis. Having myself spent nearly a year and a half doing Objective-C programming part time before learning to C#, this is a topic that hits home for me. There are a couple of areas that warrant some additional clarification, as they are obscure for most Objective-C and .NET programmers alike.

What is id?
To answer that, we must go back to the future: to 1986. Just kidding. Well, not really. Obj-C started life in the early 1980’s, originating as a C preprocessor that allowed programmers to create purely OOP C software in a manner very much inspired by Smalltalk (just like C# was). It eventually added a runtime, then deeper compiler extensions, but interestingly, not a standard library. Obj-C is a superset of C, and gets compiled down to C. Obj-C types must, at the end of the day, be composed of C types. Since C has no object-y primitive type itself, Obj-C needs to create one. And it does, it’s a struct called objc_object. Unlike C#, all Obj-C objects live on the heap. Instead of requiring users to write (objc_object *) all over the place, the designers mercifully declared id as alias to objc_object*. The actual C code for the definition of id is:

typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

Interestingly, the familiar NSObject root class has only one internal field: Class isa. When you write a line of Obj-C like [NSObject alloc], the compiler emits a C call to the runtime’s id class_createInstance(Class cls, size_t extraBytes) function. Notice, though, how neither that function nor id is coupled to NSObject.

As mentioned above, Obj-C does not have an “official” standard library, so it’s possible to use Obj-C without using Apple’s standard library, called Cocoa. In fact, you could just use the standard C library and create your own Object class, and id will still work with the runtime. gcc even comes with the Object class, which you can use as your root object class instead. Of course, that way lies madness.

C#/.NET works the other way around. It instead of reducing OOP (Obj-C) code down to procedural code (C), it reduces OOP code (C#) down to CIL bytecode which is OOP from the get go, with instructions like initobj and isinst. Even primitive types are all objects–yet primitive C# value types still live in the stack just like in C and Obj-C. But that is not a language feature of C#, it’s a feature of the CLS itself. In Obj-C, that all has to be handled by whatever facilities C has, which means using pointers and using malloc. id is actually quite clever, and is probably closest to something like .NET’s TypedReference struct which plays a big role under the covers there too:

String str = "My String";
TypedReference strId;
strId = __makeref(str);
Console.WriteLine(__reftype(strId).FullName); // outputs "System.String"
String result = __refvalue(strId, string);
Console.WriteLine(result); // outputs "My String"

nil vs. null
Strictly speaking nil is the value of an id variable set to 0. In the bigger picture, however, nil is an implementation of the null object pattern. C#, as noted, lacks a direct equivalent, but if it did, it would probably be referenced by calling a hypothetical static field called System.Object.Null which would return an instance of:

public class NullObject
	public new String ToString()
		return String.Empty;

	public new Int32 GetHashCode()
		return 0;

	public new Boolean Equals(Object other)
		return other.GetType() == this.GetType();

The biggest difference between Obj-C’s nil object and the null keyword in C# is that in Obj-C, it is perfectly permissible to send messages to nil. The result will usually be 0/nil, instead of the runtime raising a NullReferenceException as it does in C#.

More Smalltalk
What’s most exciting to me is that Objective-C/Cocoa and C#/.NET both share the same parent: Smalltalk. They are more alike than they are different. Shoot, for a couple of years now even Obj-C/c compiles down to an intermediate language that runs JIT-compiled in a virtual machine.

There’s a lot to be excited about, if you’re a fan of language design. I hope more C# developers pickup Objective-C like Paul, and I hope more Objective-C developers pickup C# like me.

Further reading:

  1. No comments yet.
  1. No trackbacks yet.

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

%d bloggers like this: