Enumerations
Why can I not add methods to enumerations as I can in Java? The only time I use C# enumerations anymore is for DTOs. Otherwise, I know from experience that I am going to end up with a switch statement on the enumeration when I should be using polymorphism. See below:
enum Fruit { Apple, Orange }
vs.class abstract FruitEvents
{
public static readonly Fruit Apple = new Apple(1);
public static readonly Fruit Orange = new Orange(2);
protected Fruit(int id)
{
_id = id;
}
public int Id
{
get { return _id; }
}
public abstract virtual void Peel();
private class Apple : Fruit
{
public Apple(int id) : base(id)
{}
public override void Peel()
{
// omitted for brevity
}
}
// rest omitted for brevity
}
Events are probably the worst offender. Why is there an event keyword? Why not just use the already existing multicast delegate? Is not having to encapsulate the field really worth the confusion it causes? Public events appear to be able to be referenced by outside classes. This is however not the case, some methods can only be accessed by the owner class. For even more fun try passing an event to a method. Also why not use the null object pattern with events instead of forcing me to do this every time:
public event EventHandler ButtonPushed = delegate {};
An argument against this is that invoking a null event should result in a null reference because it was never allocated. Well then why can I append to it? I can't add an element to a null list reference, then why can I append an EventHandler to a null event? The most consistent solution would be to require allocation before appending.Structs
It is very useful to be able to allocate data on the stack. Unfortunately if you have any references to classes, then your struct gets boxed and goes on the heap. Structs should have been named value, so as not to confuse them with the unrelated C++ structs and to be more intention revealing. Also the compiler should prevent you from referencing any classes, as to preserve the benefits of stack allocation.
// this shouldn't compileNullable<T>
struct Currency
{
public int Dollars;
public int Cents;
public string Symbol;
}
// this should compile
value Currency
{
public int Dollars;
public int Cents;
}
A coworker introduced me to this one inspired by his learning of Haskell and the Maybe monad. References to classes should be NOT nullable by default. References to classes that can be null should be marked with a ?. Imagine how useful it would be to know which variables could be null and the convention was enforced by the compiler?
public static void MethodToCall(RequiredArg reqArg, OptionalArg? optional);While C# as a a language definitely has its benefits over Java, there are still some warts that could definitely be fixed.
// should not compile
MethodToCall(null, null);
// should compile
MethodToCall(new RequiredArg(), null);
With regard to the comparison to Java, what do you mean by a 'proper implementation of generics'? I'm no Java expert - I would just like to know.
ReplyDeleteJava generics use type erasure and do not allow for primitives.
ReplyDeletehttp://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java#Generics
graham, please check code.google.com/p/ofxware
ReplyDeleteit's a simple app (mainly for demostration purposes) that uses retlang c#
i'd like to get your feedback regarding the app architecture, specifically the bus class and how fibers/channels are being created/used
thanks !
Lance,
ReplyDeleteThe repository above does not appear to have any files in it.
Graham,
ReplyDeletePlease select repository "dev".
I'm a bit new to mercurial/mercurial on google code, so i think i basically set it up wrong. need some time to check out how to properly do it. :)
the code i'm mentioning is mostly in hg/src/Models
Lance, can you send me an email address so we can discuss the code you posted?
ReplyDeleteGraham, sure. You can reach me at lboregard (at) gmail.com
ReplyDelete