|
Those of you who have been using Orcas CTPs, or CTPs that don't even have the Orcas name on them (such as the LINQ Previews from way back in May '06, etc) are familiar with LINQ and maybe even LINQ to Entities and LINQ to DataSets. I've posted a few blog entries on these features. All of those features are made possible through a new low-level language feature in C# (and VB.NET, though I like to pretend that VB.NET doesn't exist) called language extension. A language extension is really just a slick way of adding code to an existing class. You can add code to any class, whether or not you are the one who wrote it. The only restriction that I'm aware of is that your language extension can only access public members of the original class (unless you're like me and you know how to cheat using Reflection...)
A C# language extension to the string class might look something like this:
static class StringExtender
{
public static string DoSomethingFancy(this string input)
{
...
}
}
This enables you to write code like this:
string x = "Hello World";
Console.WriteLine(x.DoSomethingFancy());
Depending on which build of Orcas you have, this might generate warnings, but it will compile and you will invoke the DoSomethingFancy() method on the string.
Here is where I admit to having been a narrow-minded C# developer. When anyone works with a single technology for as long as I've worked with .NET and C#, you tend to get myopic (which is a bad thing for someone like me). Without even being aware of it, you tend to assume that everything in front of you on a daily basis is the sum total of the programming world. It becomes easy to assume that fantastically cool new features being added to your favorite language of all time are exclusive to that language. See, I assumed that C# was the only language cool enough (remember what I said about VB.NET not existing) to get language extension capabilities.
Turns out that Objective-C has had class/object extension facilities since the dawn of time. I can't find a concrete reference, but it looks like it's been around in Objective-C since well before OS X, back in the NeXT days or earlier (can any of you long-time Apple folks confirm when Categories first appeared?).
Objective-C allows you to dynamically extend and reshape existing classes through a facility known as Categories. Actually, the language extension capability of categories is a secondary effect. The true purpose of categories is to allow you to categorize similar sets of functionality that belong to multiple classes - for example, if you are creating a custom set of methods that apply to 5 or 6 different classes, you could actually store those methods in the same file, and have them apply to 5 ot 6 different classes. Purists might slap me in the face for saying this, but Categories feel sort of like compile-time aspects in a way - far more than just simple language extensions. Categories are also designed to allow for simplification of the development process when multiple developers are contributing code to the same large class. Each developer could be working on one particular aspect (pun intended) of the class' overall functionality, each stored in their own category. Whether a project like that needs to be refactored into multiple classes is outside the scope of this article :)
Anyway, here's what the header (.h) for an Objective-C category looks like:
// need to be able to locate the declaration of the original class
#import "ClassName.h"
@interface ClassName ( CategoryName )
- (void)doSomethingFancy;
@end
In the above sample, ClassName is the name of the class being extended, such as NSString or perhaps a class from your own project. And here's what the implementation of a category looks like:
#import "CategoryName.h"
@implementation ClassName ( CategoryName )
- (void)doSomethingFancy {
// implementation
}
@end
Admittedly I had a juicier sample of an Objective-C category, but I don't have access to the MacBook Pro at the moment. Note that the implementation imports the header file for the category (the .h displayed previously), and not the header file for the original/source class. So, to add the doSomethingFancy method to the NSString class in Objective-C, your header for the category might look like this:
@interface NSString ( FancyAddOns )
- (void)doSomethingFancy;
@end
So I yet again stumble on something that I think is shiny and new in C# when I realize that it's been around in several places probably since I was in diapers.
yes but can objc be used to create websites since almost all the apps we
get asked to build these days have this requirement? ;)
I’ve created a web applet using Cocoa. It consisted of a Foundation-based
CGI (using a C library to handle the environment variables and so forth)
which communicated with a server process based on AppKit (because it
generated PDFs, which can’t easily be done in a command-line process). I
would’t reccomend this approach, but it certainly can be done.
Not sure what creating websites has to do with extending existing classes
through categories or Orcas language extensions in C#. To the best of my
knowledge, if you want websites on a Mac, use Ruby or WebObjects.
it has nothing to do with the post - I just one of these objc topics and
asked the question, I love all these different languages and tools but hey,
if you can't make a site out of it - its not much use .. .to me, just me
others might like client apps still :)
The first major web application server, NeXT's WebObjects, was originally
built in Objective-C atop the OpenStep frameworks (Cocoa's direct
predecessor).
The true purpose of categories is to allow you to categorize similar
sets of functionality that belong to multiple classes - for example, if you
are creating a custom set of methods that apply to 5 or 6 different
classes, you could actually store those methods in the same file, and have
them apply to 5 ot 6 different classes.
The act of splitting up a class into multiple files is often done
<i>so that you can split its functionality into related groups of
methods</i>, which is the main purpose of Categories. I mentioned
Aspects only to try and draw an analagy that might make Categories easier
to understand for those who haven't deal with the ability to dynamically
extend classes before.
It is interesting because there was a whole category of Software for NeXT
built on this capability. It was called objectware. The theory was you
could use objects already written, only write the code necessary to
customize to your app. This was considered a major advantage for the
NeXTstep development environment. It actually made a great deal of sales
based of this feature.
> if you can't make a site out of it - its not much use .. .to me
>riiiiight, thats a nice closed minded statement James.
Kevin, I still don't see how Objective-C categories fit the "you could
actually store those methods in the same file, and have them apply to 5 ot
6 different classes" part of your post; I also don't follow how categories
allow you to "categorize similar sets of functionality that belong to
multiple classes". Categories only apply to a single class and its
descendants, so I'm not seeing how either of the quoted statements are
accurate at all. I'm very open to being wrong, though -- I'm pretty sure
I've never written a single category yet.
James, show me in my post where I said anything about Windows, C# or any
other Microsoft technology?? You have no idea what I'm using.
Grady, what I meant was you could use a single file to contain the
implementation of a category for multiple classes. For example, to add a
method called "myFoo" to 10 different classes, you could, in theory, do
that through a single myFoo.h and myFoo.m file, even though you're defining
a category that goes to 10 different classes. At least that's my
understanding anyway :)
If you aren't building web apps on Windows, then what in the world do your
first two posts mean?
So, does C# fully incorporate "The three pillars of Object Orientation"?
I think the classes are there form the beginning. I found classes on a
lecturer webpage (University Darmstadt, Germany) They based on the book
Object Oriented programming from
Cox/Novobilski 1991 Addison-Wesley. NeXT acquired from Stepstone 1988/87
the Version 2.0 from Objective C and portet Version 4.0 as the first NexT
Version.
categories were intended to serve 2 purposes. It allows you to extend a
class with out inheriting from it and poluting the object space. It also
allows you to use it as an informal protocol when it is a category on
NSObject, meaning that its like a protocol but you only have to implement
the methods you need. Sort of like an abstract base class that provides
default implementations, and subclasses override the implementations they
don't like. Hence the name informal protocol.
I think this feature has been available in smalltalk since the 70's. i
know that a technique used by smalltalk programmers when they have a
polymorphic method spread amonst classes (like an interface in java/C#)
they often will also give Object the method that just raises an exception
to let the programmer know they are using an object that doesn't fit the
pattern (yet) if it's being incorrectly used (since all non-intended
classes will inherit they exception-throwing-version of the method from
Object.)