Friday, April 15, 2005

Where's the # in C#?

I'm one of the lucky ones to go from Delphi to C#.

Lucky, because the two languages share their intellectual father, Anders Hejlsberg, who copied many existing Delphi and C++ language concepts to C#

This means that Delphi programmers have a big advantage to Visual Basic programmers because they're already familiar with inheritance, polymorphism. Even to C++ coders who lack interfaces, events and delegates, and a even proper IDE (except for the very underrated Borland C++ Builder maybe).

I know that c++ got it's name from the incremental operator (c++ as a next iteration of C), but where did C# get it's pound suffix from?

Still I'm disappointed to miss some features that are available in Delphi, but not implemented in C#, like:

Delegate by Interface

In delphi it's possible to delegate the complete implementation of an Interface to a property. This way you don't have to redeclare each interface member inside the class, but it is possible to pass it to functions that need a IMyInterface Implemenation:

IMyInterface = interface (IInterface)
  function Foo() : Boolean;
  procedure Bar();
end;
TMyInterfaceImpl = class ( IMyInterface )
  function Foo : Boolean;
  procedure Bar() ;
end;
TMyType = class ( TObject, IMyInterface )
 private 
    FMyImplementation : IMyInterface;
  protected 
    function GetImplementation() : IMyInterface;
  public property MyImplementation : IMyInterface 
    read GetImplementation 
    implements IMyInterface;
end;
   
function TMyType.GetImplementation() 
begin
  if not assigned (FMyImplementation then 
    FMyImplementation := TMyInterfaceImpl.Create();
  result := FMyImplementation;
end;

Currently in C# you have to redeclare each member and delegate it to the implementation if you want separate your interface implementation from the class :

public interface IMyInterface {
  bool Foo();
 void Bar();
}

public class MyInterfaceImpl : IMyInterface {
  bool IMyInterface.Foo(){ ... }
  void IMyInterface.Bar(){ ... }
}

public class MyType : IMyInterface {
 IMyInterface myImplementation;
 IMyInterface MyImplementation{
   get 
   {
     if (myImplementation==null)
       myImplementation = new MyInterfaceImpl();
     return myImplementation;
   }
 }

// All members have to be redeclared even though 
// the implementation is delegated to the 
// MyImplementation property

  bool IMyInterface.Foo(){ 
    return MyImplementation.Foo();
  }
  
  void IMyInterface.Bar(){ 
    MyImplementation.Bar();
  }
}

Strictly Typed Types

In Delphi it's possible to declare a variable, that contains a reference to the class of a type, and can be used as a type. I know that sounds a little complex (don't even know if it's correct) but an example should clarify:

TMyType = class ( TObject, IMyInterface )
 private 
    FMyImplementation : IMyInterface;
  protected 
    function GetImplementation() : IMyInterface;
  public property MyImplementation : IMyInterface 
    read GetImplementation 
    implements IMyInterface;
end;

TMyTypeClass = class of TMyType;

function CreateInstance(AType : TMyTypeClass):TMyType
begin
  result := AType.Create();
end;

procedure Main()
 var MyType : TMyType;
begin
  MyType := CreateInstance(TMyType);  
end;

Now it's only possible to pass a type that inherits from TMyType.

Why doesn't c# have anything like this? C# only knows the Type type, and if you would want a method to only accept a certain type, you need to do it like this:

public MyType CreateInstance(Type type){

  if( !type.IsSubclassOf( typeof(MyType) ) )
    throw new ArgumentException("Type parameter is of incorrect type");

  return Activator.CreateInstance(type);
} 

public static void Main(){
  MyType instance = CreateInstance(typeof(MyType));
}

Type Suffices and Generics in C# 2.0:

With generics in C# 2.0 it's possible achieve something like strictly typed types, using the where keyword in generics, wich will force the collection to only accept members that implement ICloneable:

public class CloneableCollection<T> : Collection<T>, ICloneable where T : ICloneable
{
  
  public CloneableCollection<T> Clone() {
    CloneableCollection<T> collection = new CloneableCollection<T>();
    
    foreach (T o in this)
      collection.Add( (T) o.Clone() );
    
    return collection;
  } 

  object ICloneable.Clone() {
    return this.Clone();
  }
}

In C# 2.0, types can contain certain suffices to express additional compiler functionality:

<Type> - expresses a generic type, for example Collection<MyType> for a strictly typed collection.

? - expresses a value type that can contain a null value, for example

int myValue = null;

is impossible, but when declaring it as Nullable:

int? myValue = null;

it is possible. The question mark is actually a shorthand for the generic type Nullable<T>, so Nullable<int> and int? are in fact the same.

Too bad they didn't implement a NotNullable type for non-value types, using the ! (exclamation mark):

// doesn't compile
MyType! myType = null;

This is however, it is implemented in the Cω Language (pronounced COmega), a C# variant with support for type-safe support for table and document manipulation (in other words: strictly typed SQL and strictly typed XML)

COmega also supports for the * (stream) operator. This might confuse C++ developers, however it has nothing to do with a pointer. The stream operator can be seen as a array, but of unspecified length, or a dynamic strictly typed (lazy) collection. If a type contains this suffix, it both implements the C# IENumerable (edit: was C# INumerable) and the IEnumerator interface, and the values are dynamically returned as the collection is iterated:

// generate s, s+1, ..., e
static int* FromTo(int s, int e) {
for (int i = s; i <= e; i++) yield return i;
}
public static void Main() {
int* OneToTen = FromTo(1,10);
// prints 1, ..., 10
foreach(int j in OneToTen){
Console.WriteLine(j);
};
}

In other words, the for-loop in FromTo, continues only if the next value is requested by the iterator. In this case the foreach loop through the entire collection, so for every value between 1 and 10 the for loop is executed. This creates great possibilities for ASynchronous communication like reading a large recordset from a database, because the next record is only fetched when it's requested, somewhat like the DataReader class, but in a strictly typed way.

And the point is...

Here I finally come to my point. Both the where and typeof keywords are essentially performing the same function, where I think the typeof isn't event necessary now, because there's no reason why this syntax shouldn't work, because MyType is already a type, why is the extra typeof() call necessary?

public MyType CreateInstance(Type type){
  return (MyType) Activator.CreateInstance(type);
} 

public static void Main(){
  MyType instance = CreateInstance(MyType);
 // instead of
  // MyType instance = CreateInstance(typeof(MyType));
}

My proposal for C# 3.0 would be to replace them both with the Type# syntax, finally giving the # (pound) a function in C#, wich performs the same functionality as the Delphi "TMyTypeClass = class of TMyType" syntax.

Additionally, you would be able to use this as a typeof specifier in a method, and this could be our previous example rewritten, without having to specify:

public MyType CreateInstance(MyType# type){
  return (MyType) Activator.CreateInstance(type);
} 

public static void Main(){
  MyType instance = CreateInstance(MyType);
}

This could even give the previous ICloneableCollection<T> a easier to read look, and conforms more to the C# syntax:

//public class CloneableCollection<T> : Collection<T>, ICloneable where T : ICloneable
public class CloneableCollection<ICloneable# T> : Collection<T>, ICloneable
{
  
  public CloneableCollection<T> Clone() {
    CloneableCollection<T> collection = new CloneableCollection<T>();
    
    foreach (T o in this)
      collection.Add( (T) o.Clone() );
    
    return collection;
  } 

  object ICloneable.Clone() {
    return this.Clone();
  }
}

And, last but not least, it would eliminate 2 extra keywords, wich must be important to Microsoft as well, because they're very proud of the low amount of keywords in C#.

I'd like to hear your comments on this.

5 Comments:

At 2:01 AM , Anonymous Anonymous said...

Smalltalk has all that.

 
At 1:20 PM , Blogger Wiebe Tijsma said...

Great... Don't work with Smalltalk though.

 
At 2:49 PM , Anonymous Anonymous said...

In answer to your question "where does C# get it's name from?", I've always thought that the pound suffix in C# was a continuation of the C++ joke/fun;

If you look closely at the '#' it is made up of 4 italic '+' plus signs. So I see it as C was incremented to become C++ and then C++ incremented (another set of '++' added) to become C#.

Maybe it's just me, and nobody else sees it that way, but if they meant it to be interpreted as that then it's a very witty name.

 
At 12:24 PM , Blogger Wiebe Tijsma said...

Yes, I've heard that theory before as well, it does seem the most likely to me.

I really dislike names anyway that have 'implicit pronounciations', i.o.w. non-alpha or single alpha characters pronounced as a word. (business2business, losew8, .net, c#, 1d84u2day, etc. etc.).

It's very localization- and search engine unfriendly, I still don't know wether to search for C#, CSharp or CPound ;-)

(for more perversions of C# see this post ;-) http://www.thedailywtf.com/forums/25129/ShowPost.aspx)

 
At 11:26 AM , Blogger Guard said...

Hmm, I remember it was claimed somewhere on MS site that this sign is actually not a number/pound (#), but a music sharp, having really it's own typographical symbol.

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home