‘Stupid’ Question 31: What's the deal with String and string in C#?
[To celebrate my first year of programming I will ask a ‘stupid’ questions daily on my blog for a year, to make sure I learn at least 365 new things during my second year as a developer]
To String or not to string, that is the question
I had to ask. There is ‘String’ and then there is ‘string’. When I did internship I noticed in the legacy code that the previous developers had been very fon of the String usage instead of string. And I was curious what was ‘right’. So, what is the deal with String and string? You know what I found out? That this was one of the most upvoted questions on Stackoverflow!
‘String’ and ‘string’ is the same, string without the uppercase is an alias for the String type. Alias definition: “an alternate name for someone or something”. They are both compiled to System.String in Intermediate Language (low level language that C# code is compiled to). There is no performance difference.
There we go! The answer!
As for when to use it, it is debated. I use option A (and I did see this example used a fair bit on SO)
A) string when you are reffering to an object, String when you are reffering to the class
B) Always use string (the alias)
C) Always use String
D) Randomize it (probably not a good idea ;) )
Leave a comment (via email)
String is to string was Int is to int. The lower-case types are aliased to the BCL (upper-case types). The lower-case types pretend to be C# built-in types. and they are. They are the ones to use in C#. The Capitalized ones are explicitly calling out their BCL membership, which one might do in cross-language code. I would not do that. Any developer worth her salt knows that C# string maps to BCL String. We're coding in C#, so use string. BTW, it may not be Int, but rather Integer. I don't know for sure as I never use and Int. I'll always use and int.
I also prefer option A. Unfortunately, the ReSharper refactor "Use string.format" always uses "string.Format" instead of "String.Format" so I always have to change that myself. Does anyone know of a way to tell ReSharper to use String instead of string?
I generally use built-in alias for the types. It is recommended by StyleCop (whose goal is to define guidelines to enforce consistent style and formatting and help developers avoid common pitfalls and mistakes). Not all agree to this, but it is a good practice to follow when coding in team.
I tend to go all in on using the aliases in my code. Variables, fields, method parameters, all get the alias. The one place I make an effort to not use them (and that would not really be a use of the alias anyway) is in names reflecting the type. I would rather call a method "GetInt32" than "GetInt" for instance, since that name might be exposed for use in a language tha does not have the aliases.
Hmmm... interesting, I wasn't aware that R# didn't provide that option! I had a quick look around and there are currently 4-5 fix requests to add that feature. None of them are marked as solved (one dates back 8 years), and this is the main 'thread' . Might be that I did a poor search, I can see if I can get a hold of some of the Jetbrains guys on Twitter today or tomorrow and ask :)
Interesting tool, seems to be updated and all so I might give that a try
That's how usually use them as well, and I do use String when referring to the class (String.Format example) . Mostly because that was what we were taught in school, and because the examples I've seen on MSDN do it that way.
"Any developer worth her salt knows that..." - I guess I'm not worth my salt then according to your comment above. Luckily for me, both my bosses disagree. Pew! If only they knew I was asking so stupid question! :D Let's go easy on the developers now, every single one of us can have a little slipup, lack of info etc. here and there. Considering that this question is the most upvoted question on StackOverflow I would not consider a developer not worthy of his/her job title/wage for not knowing this. And can I please edit your comment to say his/her salt? I don't think this is a particular female trait ;)
>> String is to string was Int is to int. String is to string as Int32 is to int.
Bill Wagner makes a very compelling argument for using the built in language aliases in Effective C#. I don't recall all the points, but if that book is not on your bookshelf, I highly recommend it.
Again a response on an old thread, but I couldn't bare that the right answer is missing: You should use string, unless you have a very very specific reason for it. It's actually described in the C# specs somewhere. The case is that nowadays the string alias points to System.String, but that might not be the case in future frameworks. Just as Int was changed to Int32 somewhere between net1.0 beta and net1.0 alpha. Who knows, maybe they'd want to introduce a successor to Unicode someday and start using System.UnisuccessorString. If you used string in all your code you'd probably be fine (assuming they make it backwards compatible). If you used System.String, you'd be in trouble.
An interesting idea, but it well never happen. The C Sharp specification clearly states (4.2.4) "The keyword string is simply an alias for the predefined class System.String." Once it's in a Microsoft published specification, it's virtually a legal commitment. You may wish to switch from System.String to System.UnisuccessorString, but there's no way Microsoft could force that on you. Such a change could potentially break ten of thousands applications. The makers of any of those could sue MSFT over that -- and if the broken application was one that competed directly with a Microsoft app, then they could claim the Microsoft did it deliberately to give themselves an market advantage which could start monopoly/breakup talks again.
A really stupid question, if you still read the comments, is why did they choose to add those aliases anyway? And why for only a subset of the base types? DateTime and Guid does not have an alias. Where's the value? What are the benefits? Why is it a good idea that most types are PascalCased, while a few are not? I am still searching the internet for an answer...
Last modified on 2012-08-25