tags:

views:

616

answers:

13

I was just dealing with strings, and I find myself annoyed that strings can be nullable. So, I have to have

if((teststring??string.Empty)==string.Empty)

all over the place. Would string? have been so hard for allowing nullability in the relatively few cases where it is needed (dbs, idiot user inputs, etc.). I also find myself irritated with having to export readonly interfaces in the cases where I want some form of const correctness. So, what C# language construct/decision annoys you?

EDIT: Thanks for the isnullorempty function, I hadn't seen that before! Still doesn't lessen my annoyance at it being nullable :D

+26  A: 

Testing strings for Null or Empty is best done using:

if (string.IsNullOrEmpty(testString))
{
}
Mitch Wheat
A: 

The way I have to implement properties from an interface in c# 3.0 even though they are exactly the same as the interface when I'm not changing default behaviour of auto properties.

e.g.

public interface MyInterface
{
   int MyProperty { get; set;}
}

public class MyClass : MyInterface
{
   public int MyProperty { get; set; }
}

public class MyClass2 : MyInterface
{
   public int MyProperty { get; set; }
}

public class MyClass3 : MyInterface
{
   public int MyProperty { get; set; }
}

EDIT: To address some of the comments on this. I'm not changing any default behaviour of my getter. I understand the difference between class and interface thankyou, my point is that my marking it with the interface I shouldn't have to have this property inside every implementing class unless I want to change the default behaviour of the getter or setter. Imagine 500 classes implement this interface?

Also the lack of Mixins..

Rob Stevenson-Leggett
How does this not make sense? Even though it's the same text, the meaning is very different. Interface is just saying "Property will have a getter". Class is saying "compiler, please create a private field and return it unmodified inside the getter".
Rex M
This decision makes sense to me. Without this, how would you differentiate if your interface ONLY required a property get, or only a property set? What if your class didn't use automatic properties (or was extended with logic in v2)?
Reed Copsey
Yes but what I'm saying is that once I've implemented the interface that property should be implemented behind the scenes unless I want to change it. I just find, particularly with data transfer objects that I'm writing the same code over and over.
Rob Stevenson-Leggett
I disagree. The interface is defining a contract - it shouldn't be *implicitly* generating code to fulfil the contract without anything in the class saying so.
Jon Skeet
I think you're firmly in the minority position in this one, Rob.
Marc Gravell
@Rob so how does the compiler implicitly implement int GetANumber(object foo)? Now your compiler arbitrarily determines a default method behavior and return value, which you forget to override and get a weird bug. Or get a compile error that you're not satisfying the contract.
Rex M
@Rex Only default property behaviour, I never mentioned methods. @Marc Looks that way :)
Rob Stevenson-Leggett
I also disagree. It sounds like you're pining for multiple inheritance. :-)
Christian Hayter
@Christian No I'm not. Nowhere do I mention multiple inheritance. I'm talking about C# specific autoproperties only.
Rob Stevenson-Leggett
+3  A: 

out and ref parameters

boredgeek
How would you handle it otherwise?
Jess
Return a composite object.
boredgeek
+1  A: 

Expanding on Mitch's answer.

That is actually a CLR decision, not a C# one. C# has no control over the implementation details of the BCL's System.String class.

True C# could have special cased string in the compiler and said we'll do special null checks but that would have IMHO, been a bad decision. String.IsNullOrEmpty is an acceptable compromise.

JaredPar
thanks for the explanation.
Steve
+18  A: 

Making string a reference type seems entirely reasonable to me.

It's a shame that one can't declare a variable/parameter/return type to be non-nullable though - e.g.

// Never returns null
public string! Foo()
{
}

Code contracts in .NET 4.0 will help with this, I believe - but it's a bit late to make it pervasive.

A while ago I wrote a blog entry on the mistakes of C#. To summarise that post:

C# 1:

  • Lack of separate getter/setter access for properties.
  • Lack of generics. Life would have been a lot sweeter with generics from the start.
  • Classes not being sealed by default.
  • Enums just being named numbers.
  • The "\x" character escape sequence.
  • Various things about the switch statement :)
  • Some odd overload resolution rules
  • The "lock" keyword, instead of "using" with a lock tocken.

C# 2:

  • Lack of partial methods (came in C# 3)
  • Lack of generic variance (coming in C# 4)
  • The System.Nullable class (not Nullable<T> - that's fine!)
  • InternalsVisibleTo requiring the whole public key for strongly signed assemblies instead of the public key token.

C# 3:

  • Lack of support for immutability - lots of changes improved opportunities for mutating types (automatic properties, object and collection initializers) but none of these really work for mutable types
  • Extension method discovery
Jon Skeet
nice list. I like the historical approach!
Steve
Much on the list is largely "it lacked the things that came in the next version"; yet we always survived until they were added... Some of them are genuine mistakes, though - I'll grant.
Marc Gravell
About "stuff in the next version" - some of these were just silly. Not allowing a private setter? Ick. That should have been an obvious goodness. Partial methods would have been a bit harder to spot the need. Generics was obviously required, but hard to define (i.e. more time needed).
Jon Skeet
The problem with adding generics later is that it affects the class lirbary *now*. The framework would have been a lot cleaner without the non-generic collections. Implementing IEnumerable<T> without IEnumerable would be nice too...
Jon Skeet
+4  A: 

Probably the biggest glaring hole in C# is, for me, enums.

Java enums are typesafe classes that you can give behaviour to, can implement interfaces and so on.

C#/.Net enums are just glorified ints with all the problems int constants have had going back to C and C++.

cletus
On the other hand, you can easily emulate complex Java enums by writing it as a class :pThe only thing you would miss out on is the ability to `switch` on them.
JulianR
No theres more to it than that, like controlling how many instances there are of a notional value through serialization/deserialization and so on.
cletus
A: 

Enforcement of break in a non-empty case.

Verbosity of enums, especially in case statements. If I have switch (expr) and expr is an enum, I shouldn't be forced to fully qualify each enum in each case, unless there is a naming conflict.

plinth
A: 

Not allowing co/contra-variance or access rights changes when overriding base class or implementing interface methods:

public class A
{
    protected virtual Stream method()
    {
        //...stuff...
    }
}

public class B : A
{
    // compiler borks...
    public override FileStream method()
    {
        //...more stuff...
    }
}
thecoop
A: 

Checked exceptions would have been great. I know a lot of people hate them from Java, but I think it's always enforced sanity checks, especially on I/O. I like most of the things that C# changed and/or added compared to Java, but I really would have liked them to have adopted checked exceptions. It's too late now (the .NET framework being changed to have them would break virtually every program out there) but I think it would have been better to have them.

Kevin
A: 

I hate having to type IEnumerable<MyType> all over the place. It is so hard to read. I would prefer some sort of short hand for it to make my code cleaner.

This SO post sums it up nicely.

Brian Genisio
A: 

I find it enormously irritating that so many core methods are static, especially around commonly used stuff like Strings and Arrays.

Why:

Array.Sort(myArray);
String.IsNullOrEmpty(myString);

instead of:

myArray.Sort();
myString.IsNullOrEmpty

Not saying there aren't good reasons for it and it's not a big deal, but if JS can manage it, why can't C#? *

Also the switch implementation. I really think they should have trusted us with fallthrough.

* Come to that I miss JS's closure syntax too.

annakata
A: 

I don't like IDisposable/Dispose etc. Coming from C++ it is very annoying to find yourself having to think about memory management in C#. The using statement is fine if the disposable object is only used in one function. If it has to be passed around you need to manually reference count or do something else to to know when you can dispose the object.

Steven
A: 

I'd like to see class objects as first class objects in the language.

This would allow you to override static methods, and declare them in interfaces.

pgb