<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx</link><description>Back when I started this blog in 2003, one of the first topics I posted on was the difference between Null, Empty and Nothing in VBScript. An excerpt: Suppose you have a database of sales reports, and you ask the database " what was the total of all sales</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9616577</link><pubDate>Thu, 14 May 2009 20:09:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616577</guid><dc:creator>Mike</dc:creator><description>&lt;P&gt;" I am occasionally asked why C# does not simply treat null references passed to “foreach” as empty collections, or treat null strings as empty strings. "&lt;/P&gt;
&lt;P&gt;Except that C# does treat nulls as empty strings sometimes:&lt;/P&gt;
&lt;P&gt;Console.WriteLine("foo" + null + "bar");&lt;/P&gt;
&lt;P&gt;This prints foobar, it doesn't print an empty string nor does it throw an exception.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Excellent point, I had forgotten that one. Which is odd, since rewriting the code generator that does those semantics was my first task when I joined this team. &lt;/P&gt;
&lt;P&gt;Those (in my opinion unfortuate)&amp;nbsp;semantics are imposed upon us by String.Concat; the addition operator is just a syntactic sugar for a call to String.Concat. The designers of String.Concat chose to treat null concatenation as empty string concatenation. Which means that (string)null + (string)null gives you an empty string in C#, bizarrely enough. -- Eric&lt;/P&gt;&lt;/DIV&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9616769</link><pubDate>Thu, 14 May 2009 21:20:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616769</guid><dc:creator>ghenne</dc:creator><description>&lt;p&gt;This is interesting. Years ago, a product call eMbedded Visual Basic, which used VBScript as its engine, had a constant of vbNullPtr that was used for API calls. Any idea what this value would pass?&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617249</link><pubDate>Fri, 15 May 2009 01:34:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617249</guid><dc:creator>Daniel Earwicker</dc:creator><description>&lt;P&gt;What's the advantage of &amp;nbsp;your special empty sequence versus Linq's Enumerable.Empty&amp;lt;T&amp;gt;()?&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Good point. There is no advantage. It makes more sense to just use the standard one. I've updated the text. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617261</link><pubDate>Fri, 15 May 2009 01:38:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617261</guid><dc:creator>Thomas Levesque</dc:creator><description>&lt;p&gt;@ghenne : it would probably be equivalent to IntPtr.Zero...&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617474</link><pubDate>Fri, 15 May 2009 04:06:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617474</guid><dc:creator>Blake Coverett</dc:creator><description>&lt;P&gt;Aww, a nostalgic post for me - I'm the same Blake from the comment thread on the original VBScript post. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;Over five years later, and this has consistently been one of my favorite Microsoft blogs. &amp;nbsp; Thanks for all the great articles, Eric.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;You're welcome, thanks for reading! -- Eric&lt;/P&gt;&lt;/DIV&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617586</link><pubDate>Fri, 15 May 2009 05:40:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617586</guid><dc:creator>Matt Sherman</dc:creator><description>&lt;p&gt;Great stuff Eric, I don't think people treat nulls as valuable information often enough. A few more thoughts: &lt;a rel="nofollow" target="_new" href="http://clipperhouse.com/blog/post/Nulls-and-knowledge.aspx"&gt;http://clipperhouse.com/blog/post/Nulls-and-knowledge.aspx&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617644</link><pubDate>Fri, 15 May 2009 06:31:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617644</guid><dc:creator>Charlie</dc:creator><description>&lt;P&gt;Thanks for another interesting post - I heartily agree that these are important distinctions for programmers to make.&lt;/P&gt;
&lt;P&gt;I also noticed Blake's comment, and went back through some of the discussion between you two from the original post. Time permitting, I would love to see a post or two about your ideas on interviewing, since I'm currently learning how to give interviews myself. How do you attempt to test problem solving ability? As I'm sure you've found, it seems a lot harder than just testing knowledge.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;I've written two articles about interviewing. See the "interviewing" archive button on the sidebar. -- Eric&lt;/P&gt;&lt;/DIV&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617649</link><pubDate>Fri, 15 May 2009 06:36:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617649</guid><dc:creator>AC</dc:creator><description>&lt;p&gt;I often see this manifested (or not manifested correctly) in data capture scenarios. It's all well and good to have strict validation, but sometimes your hapless user just doesn't know what the chassis serial number is, etc. &lt;/p&gt;
&lt;p&gt;Overzealous developers who shun nulls in the database end up at some point creating sentinel values which for obvious reasons doesn't make anything easier in the long run. Not only do you have a non-standard syntax, but you better be sure your sentinel is really never going to happen and doesn't ruin any computations in the process,&lt;/p&gt;
&lt;p&gt;Null is that special value that is outside the set of all permissible values, and I think sometimes people just think it's only the runtime scolding you from using an uninitialized reference.&lt;/p&gt;
&lt;p&gt;FYI To all the people that hate checking for null, you can always use the Null Object Pattern if it makes writing your domain code easier.&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617670</link><pubDate>Fri, 15 May 2009 07:01:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617670</guid><dc:creator>Thomas</dc:creator><description>&lt;P&gt;I'm pretty new to C#, but this has been nagging me for a bit&lt;/P&gt;
&lt;P&gt;why isn't int nullable in C#? &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class=yellowbox&gt;Nullable ints are nullable in C#. Non-nullable ints are not nullable. This seems like a sensible approach, no? -- Eric &lt;/DIV&gt;
&lt;P&gt;why does it default to 0?&lt;/P&gt;
&lt;DIV class=yellowbox&gt;Well, what value would you prefer a non-nullable int to default to? -- Eric &lt;/DIV&gt;
&lt;P&gt;int thisIsAnInt = null;&lt;/P&gt;
&lt;P&gt;throws an error on build&lt;/P&gt;
&lt;DIV class=yellowbox&gt;The syntax for nullable value types in C# is to put a question mark after the type. Try "int? x = null;" -- Eric &lt;/DIV&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617691</link><pubDate>Fri, 15 May 2009 07:22:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617691</guid><dc:creator>Charlie</dc:creator><description>&lt;p&gt;(replying to myself) Actually it looks like you _have_ already posted some other stuff specifically about interviewing, which was very interesting. Thanks again for the great blog.&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617736</link><pubDate>Fri, 15 May 2009 08:08:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617736</guid><dc:creator>Anders Borum</dc:creator><description>&lt;p&gt;Thomas, you can do:&lt;/p&gt;
&lt;p&gt;int? thisIsAnInt = null; which is equivalent to&lt;/p&gt;
&lt;p&gt;Nullable&amp;lt;int&amp;gt; thisIsAnInt = null;&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617789</link><pubDate>Fri, 15 May 2009 08:51:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617789</guid><dc:creator>tunefs</dc:creator><description>&lt;p&gt;@Thomas&lt;/p&gt;
&lt;p&gt;int is a ValueType and null does not apply to ValueTypes. Eric recently wrote an article on ValueTypes and referrenced types. That article might be worth a little of your type. (Not that it actually answers your question but it's deducing from your questing I believe it holds valueable information for you).&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617807</link><pubDate>Fri, 15 May 2009 09:03:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617807</guid><dc:creator>Mark Rendle</dc:creator><description>&lt;p&gt;I love the null coalescing operator. It's great for lazy initialisation:&lt;/p&gt;
&lt;p&gt;private List&amp;lt;Order&amp;gt; orders;&lt;/p&gt;
&lt;p&gt;public List&amp;lt;Order&amp;gt; Orders&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp;get { return orders ?? (orders = LoadOrders()); }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;I've got a post on my blog about making that thread-safe:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://blog.markrendle.net/post/Lazy-initialization-thread-safety-and-my-favourite-operator.aspx"&gt;http://blog.markrendle.net/post/Lazy-initialization-thread-safety-and-my-favourite-operator.aspx&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617883</link><pubDate>Fri, 15 May 2009 09:45:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617883</guid><dc:creator>Andrey Shchekin</dc:creator><description>&lt;P&gt;Why the coalescing operator does not support shortened form, '??=' ?&lt;/P&gt;
&lt;P&gt;(and why there is not &amp;amp;&amp;amp;= and ||= as well?)&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;The answer to every "why is feature X not implemented?" question is the same. No one designed, implemented, tested, documented or shipped that feature. You're the first person to ever ask me about this particular one in the last five years, so apparently no mob of angry programmers is banging down the door to building 41 demanding that we implement them. :-) Design, implementation, testing and documentation is expensive; we try to only implement features people actually want. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9617948</link><pubDate>Fri, 15 May 2009 10:03:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9617948</guid><dc:creator>Stephan Leclercq</dc:creator><description>&lt;P&gt;I do not agree that a string is a reference type. Strings are values just as integers are. It just happens that the .NET architecture implements them as referenced objects. That's why you had to add the "IsNullOrEmpty" kludge. A proper string can never be null, in the same was as an integer can never be null. Unless I explicitly want it, in which case I would declare it as &amp;nbsp;"string? s", in the same way as I declare a nullable integer.&lt;/P&gt;
&lt;P&gt;Ordinary collections are not values (as they are mutable objects) but immutable collections definitely are values and should be non-nullable by default.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;I agree that immutable types are logically values, and it would have been nice to represent that in the type system. I also agree that it would have been nice to build in nullability/non-nullability from day one, instead of starting with non-nullable value types and nullable reference types, then adding nullable value types, and then never adding the fourth. The next time you design a brand-new type system, keep that in mind.&lt;/P&gt;
&lt;P&gt;But as a practical matter, I'm afraid strings are reference types, and that there are good reasons for that. The pleasant fact that value types are of known size, and need not be garbage collected makes it difficult to make strings value types. Also, the fact that strings can be cheaply copied by reference instead of copying all their bits, as we do with value types, is a big perf win. Would you rather abandon these benefits in exchange for making strings value types? What's the compelling benefit of making strings into value types that pays for the massive loss of performance that would entail? -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618201</link><pubDate>Fri, 15 May 2009 12:46:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618201</guid><dc:creator>silky</dc:creator><description>&lt;P&gt;You shouldn't really talk about database null as compared to C# null. Database nulls (in MS SQL at least) are very annoying and they don't mean "data is missing" they more accurately mean "i have no idea what this is"&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;I don't understand the distinction you're drawing between "missing" and "unknown". -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;As you probably know, in SQL "where a = null" and "where a &amp;lt;&amp;gt; null" return exactly the same set of rows. You need to use "is not null". God help us all if C# used _that_ approach.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;There was considerable debate over that when nullable value types were added to C# and VB. C# chose the approach you approve of -- which makes the semantics of the equality operators inconsistent and broken, but easier to read in the common case. VB chose the approach you disapprove of -- to lift equality to nullable and be consistent about comparisons of null values. Personally I prefer VB's approach; it is less intuitive but more accurate and consistent. (Which is funny, because normally C# is the less inituitive but more precise language and VB is the more intuitive but less precise language.) -- Eric&lt;/P&gt;&lt;/DIV&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618221</link><pubDate>Fri, 15 May 2009 13:02:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618221</guid><dc:creator>anthony.tarlano</dc:creator><description>&lt;p&gt;Eric I hope you can answer my question below.. tia,&lt;/p&gt;
&lt;p&gt;@Mark in your post about thread safety your final solution is equivalent to :&lt;/p&gt;
&lt;p&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 1: private volatile OrderCollection orders;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 2: &amp;nbsp;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 3: public OrderCollection Orders&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 4: {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 5: &amp;nbsp; get&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 6: &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 7: &amp;nbsp; &amp;nbsp; return this.orders ?? Interlocked.CompareExchange(ref this.orders, new OrderCollection(), null);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 8: &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 9: }&lt;/p&gt;
&lt;p&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/p&gt;
&lt;p&gt;My question is whether that Interlocked.CompareExchange is really even necessary? &lt;/p&gt;
&lt;p&gt;Since you are using the volatile modifier on the orders field, the compiler will see that the backing field orders is a volatile field. &lt;/p&gt;
&lt;p&gt;I am not sure, but I think that will make the whole statement expression extending all the way to the end point of the statement, i.e. to the end of the return, have locked semantics.. &lt;/p&gt;
&lt;p&gt;As I said, I am not clear on this, but would not these two statements be equivalent with regard to thread safety...&lt;/p&gt;
&lt;p&gt;stmt 1: &amp;nbsp;return this.orders ?? Interlocked.CompareExchange(ref this.orders, new OrderCollection(), null);&lt;/p&gt;
&lt;p&gt;stmt 2: &amp;nbsp;return this.orders ?? new OrderCollection();&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618234</link><pubDate>Fri, 15 May 2009 13:09:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618234</guid><dc:creator>anthony.tarlano</dc:creator><description>&lt;p&gt;oops, final statements should have been&lt;/p&gt;
&lt;p&gt;stmt 1: &amp;nbsp;return this.orders ?? ( this.orders = Interlocked.CompareExchange(ref this.orders, new OrderCollection(), null) );&lt;/p&gt;
&lt;p&gt;stmt 2: &amp;nbsp;return this.orders ?? ( this.orders = new OrderCollection() );&lt;/p&gt;
</description></item><item><title>New and Notable 321</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618561</link><pubDate>Fri, 15 May 2009 17:08:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618561</guid><dc:creator>Sam Gentile's Blog (if (DeveloperTask == Communication &amp;&amp; OS == Windows)</dc:creator><description>&lt;p&gt;C#/VS2010 Null is Not Empty VS2010: On Triangles and Performance - It sure looks like the *very* soon Beta 1 will exhibit some great work on Outlining and Performance Parallel Tasks - new Visual Studio 2010 debugger window ASP.NET Tip #61: Did you know...How&lt;/p&gt;
</description></item><item><title>Interesting Finds: May 15, 2009</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618619</link><pubDate>Fri, 15 May 2009 17:29:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618619</guid><dc:creator>Jason Haley</dc:creator><description>&lt;p&gt;Interesting Finds: May 15, 2009&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618669</link><pubDate>Fri, 15 May 2009 17:49:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618669</guid><dc:creator>Filini</dc:creator><description>&lt;P&gt;This is a bit unrelated to the topic, but I started with this (to see your topic "in action")&lt;/P&gt;
&lt;P&gt;String a = null;&lt;BR&gt;var b = a + null;&lt;BR&gt;Console.WriteLine(b.Length);&lt;/P&gt;
&lt;P&gt;Then I tried using different objects, like:&lt;/P&gt;
&lt;P&gt;Form f1 = new Form();&lt;BR&gt;var f2 = f1 + null;&lt;BR&gt;Console.WriteLine(f2.Length);&lt;/P&gt;
&lt;P&gt;I was expecting compilation errors ("adding" null to a Form? "Length" of a Form?), but instead it compiles and runs just fine. The output is:&lt;/P&gt;
&lt;P&gt;System.Windows.Forms.Form, Text:&lt;/P&gt;
&lt;P&gt;So, it turns out that in "var f2 = f1 + null;" var becomes a string, and calls ToString() on f1 to concat (my guess). Is it so? And if yes, why? Why am I able to add a Form to a null, and get a String? I'm probably missing something in how "var" works...&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Though I applaud your experimental approach, rather than guessing at the semantics you might consider reading the spec, which states:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The binary + operator performs string concatenation when one or both operands are of type string. If an operand of string concatenation is null, an empty string is substituted. Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. If ToString returns null, an empty string is substituted.&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, this bit is not &lt;EM&gt;perfectly &lt;/EM&gt;accurate.&amp;nbsp;Clearly in your "form" case neither operand is of type string. This bit really should say "when one or both operands can be implicitly converted to string and operator overload resolution chooses one of the built-in string concatenation operators".&lt;/P&gt;
&lt;P&gt;As I noted in Mike's comment above, I had momentarily forgotten about this unfortunate fact about string concatenation. This is not how I would have done things, but this choice was imposed upon the language by the implementation of String.Concat. It would be awfully weird to have a language where + did one thing and String.Concat did another. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618682</link><pubDate>Fri, 15 May 2009 17:58:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618682</guid><dc:creator>Seth</dc:creator><description>&lt;p&gt;Is there a vb.net equivalent for ...&lt;/p&gt;
&lt;p&gt;foreach(Customer customer in customers ?? Enumerable.Empty&amp;lt;Customer&amp;gt;())&lt;/p&gt;
&lt;p&gt;?&lt;/p&gt;
&lt;p&gt;S&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9618749</link><pubDate>Fri, 15 May 2009 18:40:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9618749</guid><dc:creator>paul</dc:creator><description>&lt;P&gt;I have a question about the construct:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;foreach(Customer customer in customers ?? Enumerable.Empty&amp;lt;Customer&amp;gt;())&lt;/P&gt;
&lt;P&gt;I haven't used the ?? operator before but the above syntax looks a little klunky to me. Take this specific example:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;int[] data = new int[] { 1, 2 };&lt;/P&gt;
&lt;P&gt;&amp;nbsp;foreach ( int i in data ?? Enumerable.Empty&amp;lt;int&amp;gt;() ) {}&lt;/P&gt;
&lt;P&gt;in the above case if I just include System and not an System.Linq I get a compiler error. Why should I have to include Linq specific code for this? The foreach is "Linq independent" so it seems to me that maybe there should be a new keyword or contextual keyword to make this a little cleaner? We have foreach. We have default. Maybe DefaultEmptyCollection&amp;lt;int&amp;gt; which uses an array :)&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;The "Enumerable" class is in the System.Linq namespace. That's where all the rest of the LINQ sequence operators are, so it's a sensible place. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Paul.&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9619790</link><pubDate>Sat, 16 May 2009 00:18:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9619790</guid><dc:creator>Steven</dc:creator><description>&lt;P&gt;"The pleasant fact that value types are of known size, and need not be garbage collected makes it difficult to make strings value types. Also, the fact that strings can be cheaply copied by reference instead of copying all their bits, as we do with value types, is a big perf win."&lt;/P&gt;
&lt;P&gt;Eric, I don't agree with you. It's pretty easy to make a string a value type (but the value must internally always contain a reference to a char array). The value would then always have the same size as the size of a reference (32 bits on x86) and copying is safe and just as fast as copying an integer or a reference. I believe the real reason not to implement it as value type is because this would lead to large amounts of boxing, especially in CLR 1.0 applications, where there was no generics.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Well, sure,&amp;nbsp;I suppose. But I don't understand the &lt;EM&gt;point&lt;/EM&gt;. I mean, we could cut out all the character array rigamarole and just say that struct MyString { public String theRealString } is a "value typed string". What does that buy us?&lt;/P&gt;
&lt;P&gt;Taking a storage location which can&amp;nbsp;contain a 32 bit managed reference to a string and reinterpreting it as storage of MyString doesn't change anything germane, it just makes it harder to take advantage of the underlying ref type. We can take _any_ reference type and explicitly wrap a value type around the reference; that just makes it slightly harder to compare things by reference. &lt;/P&gt;
&lt;P&gt;It doesn't change the fundamental fact that the _data storage_ is ultimately implemented using reference semantics. Essentially what this example highlights is that &lt;EM&gt;references&lt;/EM&gt; are themselves &lt;EM&gt;values&lt;/EM&gt;. &lt;EM&gt;References&lt;/EM&gt; are already treated as value types; the interesting thing about them is &lt;STRONG&gt;that they refer to something&lt;/STRONG&gt;, not that they're copied around by value.&lt;/P&gt;
&lt;P&gt;Making string, or any type, a "shallow" value type is trivial -- so trivial that it's not very interesting. Such a beast&amp;nbsp;still has the &lt;EM&gt;fundamental&lt;/EM&gt; property of reference types: &lt;STRONG&gt;that it refers to something else.&lt;/STRONG&gt; Making it deeply a value type, the way, say, int is, so that it &lt;EM&gt;refers&lt;/EM&gt; to nothing, that's a what I meant by it being a lot more difficult. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Just for fun, here is a non-nullable string implementation (named 'vstring') as value type :-)&lt;/P&gt;
&lt;P&gt;public struct vstring : IComparable&amp;lt;vstring&amp;gt;, IEnumerable&amp;lt;char&amp;gt;, IEnumerable, IEquatable&amp;lt;vstring&amp;gt;&lt;/P&gt;
&lt;P&gt;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;private readonly string value;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public vstring(string value)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.value = value;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public vstring(char[] value)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.value = new string(value);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;// Never returns null.&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public override string ToString()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return value ?? string.Empty;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public override int GetHashCode()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.ToString().GetHashCode();&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public int CompareTo(vstring other)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.ToString().CompareTo(other.value ?? string.Empty);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public IEnumerator&amp;lt;char&amp;gt; GetEnumerator()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.ToString().GetEnumerator();&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;IEnumerator IEnumerable.GetEnumerator()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.GetEnumerator();&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public bool Equals(vstring other)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return this.ToString().Equals(other.value ?? string.Empty);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public vstring ToLower()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return new vstring(this.ToString().ToLower());&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public vstring ToUpper()&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return new vstring(this.ToString().ToUpper());&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public static bool Equals(vstring a, vstring b)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return a.ToString() == b.ToString();&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public static bool operator ==(vstring a, vstring b)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return Equals(a, b);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public static bool operator !=(vstring a, vstring b)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return !Equals(a, b);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;public static vstring operator +(vstring a, vstring b)&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return new vstring(a.value + b.value);&lt;/P&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;
&lt;P&gt;}&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9621466</link><pubDate>Sat, 16 May 2009 09:39:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9621466</guid><dc:creator>Stephan Leclercq</dc:creator><description>&lt;p&gt;&amp;gt;&amp;gt; Would you rather abandon these benefits in exchange for making strings value types? &lt;/p&gt;
&lt;p&gt;Eric,&lt;/p&gt;
&lt;p&gt;Don't get me wrong. I'm not saying that they shoud be *implemented internally* as value types (ie being allocated on stack, copied bit by bit every time the wind blows, etc.) but they should *appear to the programmer* as value types (ie never be null, and instead initialized by default to the empty string, etc...) That's one of the too rare things Borland Delphi does right :-)&lt;/p&gt;
&lt;p&gt;Basically that's almost just syntactic sugar : every time you see a string declaration, initialize it to String.Empty instead of null, and catch every assignation of null to a string (including return statements.)&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9622799</link><pubDate>Sat, 16 May 2009 16:07:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9622799</guid><dc:creator>Steven</dc:creator><description>&lt;p&gt;&amp;gt;&amp;gt; Well, sure, I suppose. But I don't understand the point.&lt;/p&gt;
&lt;p&gt;There is no point in doing that and it won't buy us anything, expect that programmers would see strings as value types, which is the point Stephan Leclercq tried to make. While I understand Stephan’s point, I’m against doing this. While strings then would really represent a logical value, this might give developers the wrong impression that strings would be copied completely by value, which could never be the case, because this -as you said- would be disastrous for performance.&lt;/p&gt;
&lt;p&gt;So I didn’t disagree on string being a reference type, I only disagreed on the arguments you gave against string not being a value type.&lt;/p&gt;
&lt;p&gt;ps. I saw my code example 'exploded' on your blog. It now takes a lot of space, sorry for that.&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9624498</link><pubDate>Sun, 17 May 2009 22:38:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9624498</guid><dc:creator>Pavel Minaev [MSFT]</dc:creator><description>&lt;p&gt;&amp;gt;&amp;gt; But as a practical matter, I'm afraid strings are reference types, and that there are good reasons for that. The pleasant fact that value types are of known size, and need not be garbage collected makes it difficult to make strings value types. Also, the fact that strings can be cheaply copied by reference instead of copying all their bits, as we do with value types, is a big perf win.&lt;/p&gt;
&lt;p&gt;This does not preclude from String being a value type. It just has to be a value type that encapsulates a single reference to an internal &amp;quot;StringData&amp;quot; reference type, with the latter working exactly as System.String works today. So user sees a value type, with no null value, and the implementation still gets all the benefits of a reference types.&lt;/p&gt;
&lt;p&gt;&amp;gt;&amp;gt; While strings then would really represent a logical value, this might give developers the wrong impression that strings would be copied completely by value&lt;/p&gt;
&lt;p&gt;It wouldn't matter in the slightest. Since strings are immutable, there are no observable effects between a copying implementation, and a sharing implementation (well, except for Object.ReferenceEquals, but why would you care about that one?). So it doesn't really matter what impression developers get - it will be consistent with behavior either way.&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9625417</link><pubDate>Mon, 18 May 2009 18:25:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9625417</guid><dc:creator>eff Five</dc:creator><description>&lt;p&gt;&amp;quot;The designers of String.Concat chose to treat null concatenation as empty string concatenation. &lt;/p&gt;
&lt;p&gt;Which means that (string)null + (string)null gives you an empty string in C#, bizarrely enough&amp;quot;&lt;/p&gt;
&lt;p&gt;MS SQL has the same behavior if you SET CONCAT_NULL_YIELDS_NULL OFF &amp;nbsp;which happened to have burned me last week because two different apps set it differently.&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9625665</link><pubDate>Mon, 18 May 2009 21:04:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9625665</guid><dc:creator>Michael</dc:creator><description>&lt;P&gt;"Explain the difference between Null, Empty, and Nothing" has been one my favorite interview questions for years. I've always enjoied the null/empty/nothing stares after I ask that question.&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Does the answer to question really tell you much about the candidate? If they've claimed to be a VB expert then that will certainly tell you whether they are or not I suppose. But I try to ask interview questions that allow the candidate to demonstrate skills, intelligence or passion rather than testing domain-specific knowledge. I assume that anyone who is smart, skilled and gets stuff done can learn the domain. -- Eric&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9626011</link><pubDate>Mon, 18 May 2009 23:55:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9626011</guid><dc:creator>I. J. Kennedy</dc:creator><description>&lt;p&gt;&amp;quot;The designers of String.Concat chose to treat null concatenation as empty string concatenation.&amp;quot;&lt;/p&gt;
&lt;p&gt;Hopefully these designers have been re-assigned. &amp;nbsp;:^)&lt;/p&gt;
&lt;p&gt;Seriously, not a good design decision in my humble opinion. It only masks problems and adds to the newbie confusion between null and the empty string. I guess it's too late to turn back though.&lt;/p&gt;
</description></item><item><title>Null – не то же самое, что Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9639455</link><pubDate>Mon, 25 May 2009 01:22:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9639455</guid><dc:creator>Блог Эрика Липперта (перевод)</dc:creator><description>&lt;p&gt;Когда я начал этот блог в 2003 году, один из первых постингов был про отличия между Null, Empty и Nothing&lt;/p&gt;
</description></item><item><title>re: Null Is Not Empty</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/14/null-is-not-empty.aspx#9688405</link><pubDate>Wed, 03 Jun 2009 03:47:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9688405</guid><dc:creator>t-scotmc</dc:creator><description>&lt;P&gt;Now that there's int?, I really want things like IEnumerable!, which would never be null, so I can stop getting forced to deal with "no information" in the places where it's really not appropriate.&lt;/P&gt;
&lt;P&gt;Then have the compiler force people to do something like this before calling me:&lt;/P&gt;
&lt;P&gt;IEnumerable&amp;lt;T&amp;gt;! seq = annoying ?? Enumerable.Empty&amp;lt;Customer&amp;gt;();&lt;/P&gt;
&lt;DIV class=yellowbox&gt;
&lt;P&gt;Microsoft Research makes a language called Spec# which has a non-nullable ref type system; you might want to check it out. Also, the next version of .NET will have a "contracts" system whereby you can annotate your code with contracts that describe nullability; unfortunately, we are not integrating it directly into the language at this time, but still, it gets you a lot of the way there. -- Eric&lt;/P&gt;&lt;/DIV&gt;</description></item></channel></rss>