<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.simple-talk.com/community/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>Jason Crease</title><link>http://www.simple-talk.com/community/blogs/jcrease/default.aspx</link><description>Test Engineer - Red Gate Software</description><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>SmartAssembly Error Reporting: with the bug-finding power of more than 20 testers</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2011/09/08/103234.aspx</link><pubDate>Thu, 08 Sep 2011 13:22:34 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:103234</guid><dc:creator>Jason Crease</dc:creator><slash:comments>0</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/103234.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=103234</wfw:commentRss><description>&lt;p&gt;At Red Gate, we use the SmartAssembly automated-error reporting system in the applications we sell.&amp;#160; When an error or exception occurs 'in-the-wild', it is reported back to Red Gate HQ, along with details about the error (stack trace, deployment environment, local variables, and more). Using the '&lt;a href="http://sasync.codeplex.com/" target="_blank"&gt;SmartAssembly Sync for JIRA'&lt;/a&gt; system, these errors are then automatically filed as bugs in our JIRA bug-tracking system. I should point out that Sync-For-JIRA is rather clever - it adds stack traces, it doesn't file duplicates, etc.&lt;/p&gt;  &lt;p&gt;We have been using this system now for about a year, and were recently surprised to discover that this system files more bugs than our top 20 testers put together. SmartAssembly actually finds about 15 times as many bugs as one of our more prolific testers.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.simple-talk.com/blogbits/Jason_Crease/SmartAssemblyErrorReportingwiththebugfin_CA27/bugspie_4.png"&gt;&lt;img title="bugspie" border="0" alt="bugspie" src="http://www.simple-talk.com/blogbits/Jason_Crease/SmartAssemblyErrorReportingwiththebugfin_CA27/bugspie_thumb_4.png" width="514" height="516" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;i&gt;66% of issues (bugs, enhancements, etc) raised in the past year come from SmartAssembly Error Reporting. &lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;In the past year, we have learned &lt;i&gt;(rather embarrassingly)&lt;/i&gt; of thousands of different errors in our products.&amp;#160; In the past we would have had to rely on good-hearted customers sending us in limited amounts of reproductory data, but thanks to &lt;a href="http://www.red-gate.com/products/dotnet-development/smartassembly/error-reporting/?utm_source=simpletalk&amp;amp;utm_medium=blog&amp;amp;utm_content=aervstester-jason&amp;amp;utm_campaign=smartassembly" target="_blank"&gt;SmartAssembly Automated Error Reporting&lt;/a&gt; we can automatically get all the data we need to reproduce the bug.&lt;/p&gt;  &lt;p&gt;However, the type of bugs found by this handy tool tends to be different:&amp;#160; unhandled exceptions, crashes, and unexpected environments. On the other hand, 'flesh-and-blood' testers tend to find UI glitches, workflow problems, etc.&amp;#160; So, SmartAssembly error-reporting definitely complements real testers, rather than replaces them.&lt;/p&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=103234" width="1" height="1"&gt;</description></item><item><title>New spreadsheet accompanying SmartAssembly 6.0 provides statistics for prioritizing bug fixes</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2011/03/18/100868.aspx</link><pubDate>Fri, 18 Mar 2011 12:06:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:100868</guid><dc:creator>Jason Crease</dc:creator><slash:comments>0</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/100868.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=100868</wfw:commentRss><description>&lt;p&gt;One problem developers face is how to prioritize the many voices providing input into software bugs. If there is something wrong with a function that is the darling of a particular user, he or she tends to want action - now!&lt;/p&gt;  &lt;p&gt;The developer's dilemma is how to ascertain that the problem is major or minor, and when it should be addressed.&lt;/p&gt;  &lt;p&gt;Now there is a new &lt;a href="http://www.red-gate.com/products/dotnet-development/smartassembly/feature-usage-reporting/spreadsheet?utm_source=simpletalk&amp;amp;utm_medium=blog&amp;amp;utm_content=jasonblog-furspread&amp;amp;utm_campaign=smartassembly"&gt;spreadsheet&lt;/a&gt; accompanying SmartAssembly that provides exactly that information in an objective manner. This might upset those used to getting their way by being the loudest or pushiest, but ultimately it will ensure that the biggest problems get the priority they deserve.&lt;/p&gt;  &lt;p&gt;Here's how it works: Feature Usage Reporting (FUR) in SmartAssembly 6.0 provides a wealth of data about how your software is used by its end-users, but in the SmartAssembly UI the data isn't mined to its full extent. The new Excel spreadsheet for FUR extracts statistics from that data and presents them in easy-to-understand forms.&lt;/p&gt;  &lt;p&gt;I developed the spreadsheet feature in Microsoft Excel, using a fair amount of VBA. The spreadsheet connects directly to the database which stores the feature-usage data, and shows a wide variety of statistics and tables extracted from that data.&amp;nbsp; You want to know what percentage of users have used the 'Export as XML' button?&amp;nbsp; No problem.&amp;nbsp; How popular is v5.3 is compared to v5.1?&amp;nbsp; There's graphs for that. You need to know whether you have more users in Russia or Brazil? There's a big pie chart for that.&lt;/p&gt;  &lt;p&gt;I recently witnessed the spreadsheet in use here at Red Gate Software.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;My bug is exposed as minor&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;While testing new features in .NET Reflector, I found a usability bug in the Refresh button and filed it in the Red Gate bug-tracking system. The bug was labelled "V.NEXT MINOR," which means it would be fixed in the next point release.&lt;/p&gt;  &lt;p&gt;Although I'm a professional tester, I'm not much different than most software users when they discover a bug that affects them personally: I wanted it fixed immediately. There was an ulterior motive at play here, of course. I would get to see my colleagues put the spreadsheet to work.&lt;/p&gt;  &lt;p&gt;The Reflector team loaded up the spreadsheet to view the feature-usage statistics that SmartAssembly collected for the refresh button.&lt;/p&gt;  &lt;p&gt;The resulting statistics showed that only 8% of users have ever pressed the Refresh button, and only 2.6% of sessions involve pressing the button. When Refresh is used, it's only pressed on average 1.6 times a session, with a maximum of 8 times during a session. This was in stark contrast to what I was doing as a conscientious tester: pressing it dozens of times per session.&lt;/p&gt;  &lt;p&gt;&lt;i&gt;&lt;a href="/blogbits/Jason_Crease/New.0providesstatisticsforprioritizingbu_AA4A/reflector_refresh.png"&gt;&lt;img title="reflector_refresh" alt="reflector_refresh" src="/blogbits/Jason_Crease/New.0providesstatisticsforprioritizingbu_AA4A/reflector_refresh_thumb.png" border="0" width="590" height="180"&gt;&lt;/a&gt; &lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;The spreadsheet provides evidence that my bug was a minor one.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;On to more serious things&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Based on the solid evidence uncovered by the spreadsheet, the Reflector team concluded that my experience does not represent that of the vast majority of Reflector's recorded users. The Reflector team had ample data to send me back to my desk and keep the bug classified as "V.NEXT MINOR." The team then went back to fixing more serious bugs.&lt;/p&gt;  &lt;p&gt;If I'm in the shoes of the user, I might not be thoroughly happy, but I cannot deny that the evidence clearly placed me in a very small minority. Next time I'm hoping the spreadsheet will prove that my bug is more important.&lt;/p&gt;  &lt;p&gt;Find out more about Feature-Usage Reporting &lt;a href="http://www.red-gate.com/products/dotnet-development/smartassembly/feature-usage-reporting?utm_source=simpletalk&amp;utm_medium=blog&amp;utm_content=jasonblog-furspread&amp;utm_campaign=smartassembly"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The spreadsheet is available for free download &lt;a href="http://www.red-gate.com/products/dotnet-development/smartassembly/feature-usage-reporting/spreadsheet?utm_source=simpletalk&amp;amp;utm_medium=blog&amp;amp;utm_content=jasonblog-furspread&amp;amp;utm_campaign=smartassembly"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=100868" width="1" height="1"&gt;</description></item><item><title>Breaking through the class sealing</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2010/04/26/90758.aspx</link><pubDate>Mon, 26 Apr 2010 13:58:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:90758</guid><dc:creator>Jason Crease</dc:creator><slash:comments>11</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/90758.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=90758</wfw:commentRss><description>&lt;p&gt;Do you understand 'sealing' in C#?  Somewhat?  Anyway, here's the lowdown.&lt;/p&gt;  &lt;p&gt;I've done this article from a C# perspective, but I've occasionally referenced .NET when appropriate.&lt;/p&gt;  &lt;h4&gt;What is sealing a class?&lt;/h4&gt;  &lt;p&gt;By sealing a class in C#, you ensure that you ensure that no class can be derived from that class.  You do this by simply adding the word 'sealed' to a class definition: public sealed class Dog {}&lt;/p&gt;  &lt;p&gt;Now writing something like " public sealed class Hamster: Dog {} " you'll get a compile error like this:&lt;/p&gt;  &lt;p&gt;'Hamster: cannot derive from sealed type 'Dog'&lt;/p&gt;  &lt;p&gt;If you look in an IL disassembler, you'll see a definition like this:&lt;/p&gt;  &lt;pre&gt;.class public auto ansi sealed beforefieldinit &lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://Sealing:1.0.0.0/Sealing.Dog"&gt;&lt;strong&gt;Dog&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;extends [&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089"&gt;mscorlib&lt;/a&gt;]System.Object&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Note the addition of the word 'sealed'.&lt;/p&gt;

&lt;h4&gt;What about sealing methods?&lt;/h4&gt;

&lt;p&gt;You can also seal overriding methods.  By adding the word 'sealed', you ensure that the method cannot be overridden in a derived class.  Consider the following code:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;public class Dog : Mammal { public sealed override void Go() { } } 
    &lt;br /&gt;public class Mammal { public virtual void Go() { } }&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In this code, the method 'Go' in Dog is sealed.  It cannot be overridden in a subclass.  Writing this would cause a compile error:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;public class Dachshund : Dog { public override void Go() { } }&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;However, we can 'new' a method with the same name.  This is essentially a new method; distinct from the 'Go' in the subclass:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;public class Terrier : Dog { public new void Go() { } }&lt;/font&gt; &lt;/p&gt;

&lt;h4&gt;Sealing properties?&lt;/h4&gt;

&lt;p&gt;You can also seal seal properties.  You add 'sealed' to the property definition, like so:&lt;/p&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;public sealed override string Name 
    &lt;br /&gt;{ 

    &lt;br /&gt;    get { return m_Name; } 

    &lt;br /&gt;    set { m_Name = value; } 

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;In C#, you can only seal a property, not the underlying setters/getters.  This is because C# offers no override syntax for setters or getters.  However, in underlying IL you seal the setter and getter methods individually - a property is just metadata.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h4&gt;Why bother sealing?&lt;/h4&gt;

&lt;p&gt;There are a few traditional reasons to seal:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Invariance. &lt;/strong&gt;Other people may want to derive from your class, even though your implementation may make successful derivation near-impossible.  There may be twisted, hacky logic that could never be second-guessed by another developer.  By sealing your class, you're protecting them from wasting their time.  The CLR team has sealed most of the framework classes, and I assume they did this for this reason. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Security.&lt;/strong&gt;  By deriving from your type, an attacker may gain access to functionality that enables him to hack your system.  I consider this a very weak security precaution. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Speed.&lt;/strong&gt;  If a class is sealed, then .NET doesn't need to consult the virtual-function-call table to find the actual type, since it knows that no derived type can exist.  Therefore, it could emit a 'call' instead of 'callvirt' or at least optimise the machine code, thus producing a performance benefit.  But I've done trials, and have been unable to demonstrate this If you have an example, please share!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All in all, I'm not convinced that sealing is interesting or important.  Anyway, moving-on...&lt;/p&gt;

&lt;h4&gt;What is automatically sealed?&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Value types and structs.&lt;/strong&gt;  If they were not always sealed, all sorts of things would go wrong.  For instance, structs are laid-out inline within a class.  But what if you assigned a substruct to a struct field of that class?  There may be too many fields to fit.&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Static classes.&lt;/strong&gt;  Static classes exist in C# but not .NET.  The C# compiler compiles a static class into an 'abstract sealed' class.  So static classes are already sealed in C#.&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Enumerations.&lt;/strong&gt;  The CLR does not track the types of enumerations - it treats them as simple value types.  Hence, polymorphism would not work.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;What cannot be sealed?&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Interfaces.&lt;/strong&gt;  Interfaces exist to be implemented, so sealing to prevent implementation is dumb.  But what if you could prevent interfaces from being extended (i.e. ban declarations like "public interface IMyInterface : ISealedInterface")?  There is no good reason to seal an interface like this.  Sealing finalizes behaviour, but interfaces have no intrinsic behaviour to finalize&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Abstract classes.&lt;/strong&gt;  In IL you &lt;em&gt;can&lt;/em&gt; create an abstract sealed class.  But C# syntax for this already exists - declaring a class as a 'static', so it forces you to declare it as such.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Non-override methods.&lt;/strong&gt;  If a method isn't declared as override it cannot be overridden, so sealing would make no difference.  Note this is stated from a C# perspective - the words are opposite in IL.  In IL, you have four choices in total: no declaration (which actually seals the method), 'virtual' (called 'override' in C#), 'sealed virtual' ('sealed override' in C#) and 'newslot virtual' ('new virtual' or 'virtual' in C#, depending on whether the method already exists in a base class).&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Methods that implement interface methods.&lt;/strong&gt;  Methods that implement an interface method must be virtual, so cannot be sealed.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Fields&lt;/strong&gt;.  A field cannot be overridden, only hidden (using the 'new' keyword in C#), so sealing would make no sense.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=90758" width="1" height="1"&gt;</description></item><item><title>How big is a string in .NET?</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2009/01/16/71678.aspx</link><pubDate>Fri, 16 Jan 2009 16:32:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:71678</guid><dc:creator>Jason Crease</dc:creator><slash:comments>19</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/71678.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=71678</wfw:commentRss><description>&lt;P class=MsoNormal&gt;How big is a string in .NET?&lt;/P&gt;
&lt;P class=MsoNormal&gt;Typically the size of an object is 8 bytes for the object header plus the sum of the fields.&amp;nbsp; Consider this simple object:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class ThreeFields&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double d;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; object o;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int i;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The size of a ThreeFields object is 8 bytes (for header) + 8 bytes (for the double) + 4 bytes (for the object pointer) + 4 bytes (for the integer) = 24 bytes .&amp;nbsp; But what about a string?&lt;/P&gt;
&lt;P class=MsoNormal&gt;A string is composed of:&lt;/P&gt;
&lt;OL&gt;
&lt;LI class=MsoNormal&gt;An 8-byte object header (4-byte SyncBlock and a 4-byte type descriptor)
&lt;LI class=MsoNormal&gt;An int32 field for the length of the string (this is returned by String.Length).
&lt;LI class=MsoNormal&gt;An int32 field for the number of chars in the character buffer.
&lt;LI class=MsoNormal&gt;The first character of the string in a System.Char.
&lt;LI class=MsoNormal&gt;The rest of the string in a character buffer, terminating with a null terminator char.&amp;nbsp;&amp;nbsp; If you don’t believe me about the null-terminator, have a poke around with Reflector.&amp;nbsp; String.AppendInPlace() demonstrates this nicely.&amp;nbsp; One reason this is done is to aid unmanaged interop.&amp;nbsp; Otherwise, everytime you marshal a string you’d need to copy it and add the ‘\0’&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;So a string size is 18 + (2 * number of characters) bytes.&amp;nbsp; (In reality, another 2 bytes is sometimes used for packing to ensure 32-bit alignment, but I’ll ignore that).&amp;nbsp; 2 bytes is needed for each character, since .NET strings are UTF-16.&amp;nbsp;&amp;nbsp; Thus, a string like so:&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;BR&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String mySimpleString = "Hello";&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Will be 18 + (2 * 5) = 28 bytes.&amp;nbsp; Splendid.&amp;nbsp; Now consider this snippet of code.&amp;nbsp; It creates a String and a Stringbuilder with the same contents.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String atCompile = "123456789";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder buildingMyString = new StringBuilder("123");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildingMyString.Append("456");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buildingMyString.Append("789");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String fromStringBuilder = buildingMyString.ToString();&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;This should create two strings: atCompile and fromStringBuilder, which both read “123456789”.&amp;nbsp; How big are atCompile and fromStringBuilder?&amp;nbsp; You might think:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18 + (2 * 9) = 36 bytes&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;But if you profile it in a memory profiler, like &lt;A href="http://www.red-gate.com/Products/ants_profiler/index.htm"&gt;ANTS Profiler&lt;/A&gt;, and you’ll see this.&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;&lt;IMG alt="Community server image manipulation is rubbish." src="/community/blogs/jcrease/attachment/71678.ashx"&gt; 
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;&lt;BR&gt;
&lt;P class=MsoNormal&gt;The String atCompile is 36 bytes, as expected. fromStringBuilder has the same contents, but is 50 bytes.&amp;nbsp; Eh?&amp;nbsp; What’s going on there?&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;This weird behaviour is down to how System.StringBuilder does a ToString().&amp;nbsp; Like most people, I believed it allocated a new string and then copied the contents of the StringBuilder in.&amp;nbsp; In reality, it just returns a reference to the string underpinning the StringBuilder.&amp;nbsp; StringBuilders work by using strings backed with char buffers increasing in size in powers of two.&amp;nbsp; A string does not need to be backed by a char buffer matching the string length; ‘expansion room’ is permitted.&amp;nbsp; In this case, fromStringBuilder is backed by a 16-byte array, so is 18 + (2*16) = 50 bytes, as observed.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;But what happens if the StringBuilder is then edited?&amp;nbsp; Doesn’t the String we just got from ToString() then become invalid?&amp;nbsp;&amp;nbsp; Yes it does.&amp;nbsp; When you do this append, StringBuilder copies the existing contents to a new string, and uses this new string.&amp;nbsp; The String we got via ToString() continues to point to the String that has been discarded by the StringBuilder.&amp;nbsp; This String is still backed by an over-sized char[].&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;I presume Microsoft made this design decision because it is a common idiom to create a StringBuilder, append to it, ToString() it, and then never use it again.&amp;nbsp; Copying all those bytes from the StringBuilder to a String would be a waste.&amp;nbsp; Even if you then append to the StringBuilder after doing your ToString(), the resulting copy of the StringBuilder‘s underlying string requires no time than would copying it during the ToString().&lt;/P&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=71678" width="1" height="1"&gt;</description><enclosure url="http://www.simple-talk.com/community/blogs/jcrease/attachment/71678.ashx" length="16552" type="image/png" /></item><item><title>Scrum: Keeping Kosher doesn’t make you Jewish</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/12/08/70797.aspx</link><pubDate>Mon, 08 Dec 2008 16:10:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:70797</guid><dc:creator>Jason Crease</dc:creator><slash:comments>1</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/70797.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=70797</wfw:commentRss><description>&lt;P class=MsoNormal&gt;Our development team has started using Scrum.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;We’re only 4 weeks in, so it would be premature to make a judgement on whether it's working for us.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I’ve investigated how it’s practised elsewhere, and there seems to be a worrying trend…&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Let’s say I want to become a Christian.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I could go to church on Sundays; receive communion; marry in a Church; sing hymns; celebrate Christmas.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;But none of these would make me a Christian.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;These are just extrinsic procedures – not core beliefs.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;To really be a Christian, you have to ‘live-for-God’; believe in the divinity of Christ; and so on.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The point of Christianity is these core beliefs, not the extraneous rituals.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;When it comes to Scrum, I always see teams faithfully having daily stand-up meetings, having retrospective meetings, calling someone a Scrummaster, etc.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;But they fail to implement the core principles of Scrum: ‘Done-is-done’, etc.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;It’s easy to practise the irrelevant rituals, yet these should not be confused with what Scrum is really about.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;Many people tell me that no one implements Scrum properly – it’s a matter of compromise and seeing what works.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I don't accept this.&amp;nbsp; It’s remarkable how readily people compromise on the core-beliefs, yet retain all the extraneous procedures.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;They give up believing Jesus is the son of God, but keep Easter.&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;This is not to say there isn’t value in some of Scrum.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Daily stand-up meetings are useful; but this hardly amounts to a vindication of Scrum.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;In the same way, some hymns are great (‘Autumn Days’ and ‘Shine Jesus Shine’ are two of my favourites) but this is not sufficient to justify becoming a Christian.&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;If you like hymns but don’t believe in the divinity of Christ, then don’t become a Christian.&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Start a choir instead.&lt;/P&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=70797" width="1" height="1"&gt;</description></item><item><title>Nullable Structs - An interesting 'Gotcha'</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/11/26/70653.aspx</link><pubDate>Wed, 26 Nov 2008 17:11:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:70653</guid><dc:creator>Jason Crease</dc:creator><slash:comments>5</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/70653.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=70653</wfw:commentRss><description>&lt;P class=MsoNormal&gt;&lt;SPAN&gt;One of the interesting new features in C# 2.0 was nullable valuetypes.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Using these, you can set valuetypes to a value, or null.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Their usage is entirely straightforward.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;For instance, to use a nullable int simply declare a variable of type int?, and then set it to a value or null.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Behind the scenes, nullable valuetypes are implemented as generic structs of type Nullable&amp;lt;T&amp;gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;When you write:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt;? i = 2;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;What you’re really writing is:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Nullable&lt;/SPAN&gt;&amp;lt;&lt;SPAN&gt;int&lt;/SPAN&gt;&amp;gt; i = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Nullable&lt;/SPAN&gt;&amp;lt;&lt;SPAN&gt;int&lt;/SPAN&gt;&amp;gt;(2);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;When you assign a value to a pre-existing nullable int, like so:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;i = 4;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;you’re really writing:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;i = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Nullable&lt;/SPAN&gt;&amp;lt;&lt;SPAN&gt;int&lt;/SPAN&gt;&amp;gt;(4);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;And when you ‘get’ the value, like so:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt; j = i;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;What you’re really writing is:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt; j = i.Value;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;The Value is a get property, and assignment is by creating a new instance of Nullable&amp;lt;T&amp;gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This is similar to strings in C#: presenting a reference type by valuetype semantics.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;This is all fine for primitives like int, double, etc. But when using structs, an interesting problem is created that lets light in on the ‘magic’ of nullable valuetypes.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Let’s say I have a struct Point, implemented as so:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;struct&lt;/SPAN&gt; &lt;SPAN&gt;Point&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;int&lt;/SPAN&gt; x, y;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;public&lt;/SPAN&gt; Point(&lt;SPAN&gt;int&lt;/SPAN&gt; px, &lt;SPAN&gt;int&lt;/SPAN&gt; py)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;x = px; y = py;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;public&lt;/SPAN&gt; &lt;SPAN&gt;override&lt;/SPAN&gt; &lt;SPAN&gt;string&lt;/SPAN&gt; ToString()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;return&lt;/SPAN&gt; &lt;SPAN&gt;"("&lt;/SPAN&gt; + x + &lt;SPAN&gt;", "&lt;/SPAN&gt; + y + &lt;SPAN&gt;")"&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Then, I write a program that creates an int and a Point, and alter them slightly:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Main(&lt;SPAN&gt;string&lt;/SPAN&gt;[] args)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt; i = 3;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(++i);&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//increment then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Point&lt;/SPAN&gt; p = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Point&lt;/SPAN&gt;(2, 4);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p.x = 1; &lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(p);&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//move left then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.ReadLine();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;No problems here.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The int and the Point will be altered as expected. &lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Now I decide that I want my int and Point to be nullable.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;So I simply add two question marks, producing this program:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Main(&lt;SPAN&gt;string&lt;/SPAN&gt;[] args)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt;? i = 3;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(++i);&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//increment then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Point&lt;/SPAN&gt;? p = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Point&lt;/SPAN&gt;(2, 4);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p.x = 1; &lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(p);&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//move left then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.ReadLine();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;But this won’t compile.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;The int? part is fine, but for the Point? part I get the error: &lt;I&gt;“'System.Nullable&amp;lt; Point&amp;gt;' does not contain a definition for 'x'”&lt;/I&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;No problem, I’ll just edit it like so:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;static&lt;/SPAN&gt; &lt;SPAN&gt;void&lt;/SPAN&gt; Main(&lt;SPAN&gt;string&lt;/SPAN&gt;[] args)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;int&lt;/SPAN&gt;? i = 3;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(++i);&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//increment then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Point&lt;/SPAN&gt;? p = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Point&lt;/SPAN&gt;(2, 4);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p. Value.x = 1; &lt;SPAN&gt;Console&lt;/SPAN&gt;.WriteLine(p);&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;//move left then print it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Console&lt;/SPAN&gt;.ReadLine();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Now you get a different compile error: &lt;I&gt;“Cannot modify the return value of 'System.Nullable&amp;lt;.Point&amp;gt;.Value' because it is not a variable”&lt;/I&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This happens because Nullable&amp;lt;T&amp;gt;.Value has no set accessor method.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Nullable value types have this ‘limitation’ for a very good reason.&lt;SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;The same thing happens is you try to edit a struct in a List&amp;lt;&amp;gt; of structs.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Consider an over-simplification of Nullable&amp;lt;T&amp;gt; with a bodged-in set accessor, like so:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;class&lt;/SPAN&gt; &lt;SPAN&gt;MyNullable&lt;/SPAN&gt;&amp;lt;T&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;private&lt;/SPAN&gt; T val;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;public&lt;/SPAN&gt; T Value&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;set&lt;/SPAN&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;val = &lt;SPAN&gt;value&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;get&lt;/SPAN&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;return&lt;/SPAN&gt; val;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;If I create a &lt;/SPAN&gt;&lt;SPAN&gt;MyNullable&lt;/SPAN&gt;&lt;SPAN&gt;&amp;lt;&lt;SPAN&gt;Point&lt;/SPAN&gt;&amp;gt; &lt;/SPAN&gt;&lt;SPAN&gt;and use it:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;MyNullable&lt;/SPAN&gt;&amp;lt;&lt;SPAN&gt;Point&lt;/SPAN&gt;&amp;gt; p = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;MyNullable&lt;/SPAN&gt;&amp;lt;&lt;SPAN&gt;Point&lt;/SPAN&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p.Value = &lt;SPAN&gt;new&lt;/SPAN&gt; &lt;SPAN&gt;Point&lt;/SPAN&gt;(2, 1);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p.Value.x = 2;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;I get a compile error on the third line: &lt;I&gt;“Cannot modify the return value of ‘MyNullable&amp;lt;Point&amp;gt;.Value' because it is not a variable”.&lt;/I&gt;&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;This is because the statement &lt;/SPAN&gt;&lt;SPAN&gt;p.Value.x = 2&lt;FONT face="Times New Roman"&gt; is equivilent to:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman"&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;Point&lt;/SPAN&gt; otherPoint = p.Value; otherPoint.x = 2;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;Which doesn’t change the underlying p.val, because otherPoint is a &lt;B&gt;&lt;I&gt;copy&lt;/I&gt;&lt;/B&gt; of p.Val.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;So when C# gives us a compile error, it is merely protecting us from editing an irrelevent copy of the underlying Point.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;In conclusion, nullable valuetypes are immutable.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;I think the C# designers intended programmers to never modify the value of a struct once one is created, nullable or not.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=70653" width="1" height="1"&gt;</description></item><item><title>Testing the speed of ANTS Profiler 4</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/09/16/69546.aspx</link><pubDate>Tue, 16 Sep 2008 13:55:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:69546</guid><dc:creator>Jason Crease</dc:creator><slash:comments>0</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/69546.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=69546</wfw:commentRss><description>&lt;P&gt;Profiling and debugging code inevitably adds overhead, and I know that it can be really frustrating. The overhead can either be small, e.g. the Visual Studio debugger, or massive, as with most performance profilers. A developer may invest in a performance profiler to optimize an algorithm that takes 10 minutes to run, and finds that when profiled it takes 2 hours to run. A top priority in the development of ANTS Profiler 4 was to make it faster than its predecessor and faster than any other profiler on the market.&lt;/P&gt;
&lt;P&gt;We have found ANTS Profiler 4 to be about eight times faster than its predecessor, ANTS Profiler 3. It is also 4 to 20 times faster at line-level profiling than other profilers on the market.&lt;/P&gt;
&lt;P&gt;I did a few speed tests and I have made a video to show how ANTS Profiler 4 compares to the fastest-known other profiler: &lt;/P&gt;
&lt;P&gt;&lt;A href="/blogbits/Jason_Crease/ANTS4/ANTS4_vs_Competitor/ANTS4_vs_Competitor.html" target=_blank&gt;ANTS Profiler 4 vs fastest known competitor&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Here it is compared to ANTS Profiler 3: &lt;/P&gt;
&lt;P&gt;&lt;A href="/blogbits/Jason_Crease/ANTS4/ANTS4_vs_ANTS3/ANTS4_vs_ANTS3.html" target=_blank&gt;ANTS Profiler 4 vs ANTS Profiler 3&lt;/A&gt; &lt;/P&gt;If you want to try out ANTS Profiler 4, you can download it from the &lt;A href="http://www.red-gate.com/products/ants_profiler/index.htm?utm_source=simpletalk&amp;amp;utm_medium=blog&amp;amp;utm_content=jason-testingspeedap4&amp;amp;utm_campaign=antsprofiler" target=_blank&gt;RedGate website&lt;/A&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=69546" width="1" height="1"&gt;</description></item><item><title>A Quick .NET Puzzle</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/07/17/62701.aspx</link><pubDate>Thu, 17 Jul 2008 17:17:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:62701</guid><dc:creator>Jason Crease</dc:creator><slash:comments>3</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/62701.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=62701</wfw:commentRss><description>&lt;P&gt;&lt;CODE&gt;&lt;SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;SPAN&gt;&lt;FONT face=Arial&gt;Just&amp;nbsp;a quick&amp;nbsp;.NET puzzle.&amp;nbsp; Does this application ever throw that ApplicationException?&amp;nbsp; If so, why?&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&lt;SPAN&gt;&lt;FONT face=Arial&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;CODE&gt;&lt;SPAN&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN&gt;using &lt;/SPAN&gt;&lt;SPAN&gt;System&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN&gt;using &lt;/SPAN&gt;&lt;SPAN&gt;System.Threading&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN&gt;class &lt;/SPAN&gt;&lt;SPAN&gt;Program&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;static long &lt;/SPAN&gt;&lt;SPAN&gt;Num &lt;/SPAN&gt;&lt;SPAN&gt;= &lt;/SPAN&gt;&lt;SPAN&gt;0&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;static void &lt;/SPAN&gt;&lt;SPAN&gt;Main&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;string&lt;/SPAN&gt;&lt;SPAN&gt;[] args&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread t1 &lt;/SPAN&gt;&lt;SPAN&gt;= new &lt;/SPAN&gt;&lt;SPAN&gt;Thread&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;ModifyNum&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;t1.Start&lt;/SPAN&gt;&lt;SPAN&gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;while &lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;true&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;long &lt;/SPAN&gt;&lt;SPAN&gt;k &lt;/SPAN&gt;&lt;SPAN&gt;= &lt;/SPAN&gt;&lt;SPAN&gt;Num&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;if &lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;k &lt;/SPAN&gt;&lt;SPAN&gt;!= -&lt;/SPAN&gt;&lt;SPAN&gt;1&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;amp;&amp;amp;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN&gt;k &lt;/SPAN&gt;&lt;SPAN&gt;!= &lt;/SPAN&gt;&lt;SPAN&gt;0&lt;/SPAN&gt;&lt;SPAN&gt;) &lt;/SPAN&gt;&lt;SPAN&gt;throw new &lt;/SPAN&gt;&lt;SPAN&gt;ApplicationException&lt;/SPAN&gt;&lt;SPAN&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;"k is not -1 or 0.&amp;nbsp;&amp;nbsp;It is " &lt;/SPAN&gt;&lt;SPAN&gt;+ &lt;/SPAN&gt;&lt;SPAN&gt;k.ToString&lt;/SPAN&gt;&lt;SPAN&gt;());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;static void &lt;/SPAN&gt;&lt;SPAN&gt;ModifyNum&lt;/SPAN&gt;&lt;SPAN&gt;()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while &lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;true&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;if &lt;/SPAN&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN&gt;Num &lt;/SPAN&gt;&lt;SPAN&gt;== &lt;/SPAN&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt;1&lt;/SPAN&gt;&lt;SPAN&gt;) &lt;/SPAN&gt;&lt;SPAN&gt;Num &lt;/SPAN&gt;&lt;SPAN&gt;= &lt;/SPAN&gt;&lt;SPAN&gt;0&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;else &lt;/SPAN&gt;&lt;SPAN&gt;Num &lt;/SPAN&gt;&lt;SPAN&gt;= &lt;/SPAN&gt;&lt;SPAN&gt;-&lt;/SPAN&gt;&lt;SPAN&gt;1&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&lt;SPAN&gt;&lt;FONT face=Arial&gt;Stuck?&amp;nbsp; Then h&lt;SPAN&gt;ere's a hint: if you change&amp;nbsp;Num from a long to an int, it never throws the exception.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=62701" width="1" height="1"&gt;</description></item><item><title>Order of Construction</title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/06/02/57964.aspx</link><pubDate>Mon, 02 Jun 2008 15:05:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:57964</guid><dc:creator>Jason Crease</dc:creator><slash:comments>3</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/57964.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=57964</wfw:commentRss><description>&lt;P class=MsoNormal&gt;&lt;B&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/B&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;For me, inheritance is often a headache.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;In particular, in what order is everything initialized?&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Consider this short C# program. &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;It creates an instance of &lt;SPAN&gt;Dog&lt;/SPAN&gt;, which derives from &lt;SPAN&gt;Animal&lt;/SPAN&gt;.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Both &lt;SPAN&gt;Dog&lt;/SPAN&gt; and &lt;SPAN&gt;Animal&lt;/SPAN&gt; have an instance constructor, a class initializer (aka a static constructor), an instance variable, and a static variable.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;&lt;PRE&gt;&lt;FONT color=blue&gt;using&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;System&lt;/FONT&gt;&lt;FONT color=gray&gt;;
&lt;BR&gt;
&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=blue&gt;namespace&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;CtorOrder
&lt;BR&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;class&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Animal
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;int&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;instanceAnimal&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;=&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Program.Print&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Animal.instanceAnimal"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;static&amp;nbsp;int&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;staticAnimal&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;=&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Program.Print&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Animal.staticAnimal"&lt;/FONT&gt;&lt;FONT color=gray&gt;);&lt;/FONT&gt;&lt;FONT color=gray&gt;
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Animal&lt;/FONT&gt;&lt;FONT color=gray&gt;()
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Animal&amp;nbsp;constructor"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;static&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Animal&lt;/FONT&gt;&lt;FONT color=gray&gt;()
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Animal&amp;nbsp;class&amp;nbsp;constructor"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;class&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Dog&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=gray&gt;:&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Animal
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;int&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;instanceDog&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;=&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Program.Print&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Dog.instanceDog"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;static&amp;nbsp;int&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;staticDog&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;=&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Program.Print&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Dog.staticDog"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Dog&lt;/FONT&gt;&lt;FONT color=gray&gt;()
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Dog&amp;nbsp;constructor"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;static&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Dog&lt;/FONT&gt;&lt;FONT color=gray&gt;()
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"Dog&amp;nbsp;class&amp;nbsp;constructor"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;BR&gt;&amp;nbsp;
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;class&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Program
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;public&amp;nbsp;static&amp;nbsp;int&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Print&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=blue&gt;string&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;s&lt;/FONT&gt;&lt;FONT color=gray&gt;)
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=black&gt;s&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;return&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;0&lt;/FONT&gt;&lt;FONT color=gray&gt;;
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;static&amp;nbsp;void&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Main&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=blue&gt;string&lt;/FONT&gt;&lt;FONT color=black&gt;[]&amp;nbsp;args&lt;/FONT&gt;&lt;FONT color=gray&gt;)
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;{
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dog&amp;nbsp;d&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=blue&gt;=&amp;nbsp;new&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Dog&lt;/FONT&gt;&lt;FONT color=gray&gt;();
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Console.WriteLine&lt;/FONT&gt;&lt;FONT color=gray&gt;(&lt;/FONT&gt;&lt;FONT color=darkred&gt;"\nPress&amp;nbsp;enter&amp;nbsp;to&amp;nbsp;continue"&lt;/FONT&gt;&lt;FONT color=gray&gt;);
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;Console.ReadLine&lt;/FONT&gt;&lt;FONT color=gray&gt;();
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT color=black&gt;}
&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&lt;BR&gt;}&lt;/FONT&gt;&lt;FONT color=black&gt;
&lt;BR&gt;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P class=MsoNormal&gt;There are eight activities here: &lt;/P&gt;
&lt;OL&gt;
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; instance constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; class constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; instance variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; static variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; instance constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; class constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; instance variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; static variable&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;The question is: ‘In what order are the eight activities run?’&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Try working it out.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Anyway, the answer is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; static variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; class constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; instance variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; static variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; class constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt; instance variable 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Animal&lt;/SPAN&gt;&amp;nbsp;instance constructor 
&lt;LI class=MsoNormal&gt;&lt;SPAN&gt;Dog&lt;/SPAN&gt; instance constructor&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;There are two things I find surprising about this:&lt;/P&gt;
&lt;OL&gt;
&lt;LI class=MsoNormal&gt;Why do static constructors run from most derived class to least derived class, i.e. &lt;SPAN&gt;Dog&lt;/SPAN&gt; then &lt;SPAN&gt;Animal&lt;/SPAN&gt;? 
&lt;LI class=MsoNormal&gt;Why do instance variables get initialized before calling the parent’s instance constructor?&lt;/LI&gt;&lt;/OL&gt;
&lt;P class=MsoNormal&gt;The answer to question 1 is that Dog’s class initializer has to be run since we are running Dog’s instance constructor, but &lt;EM&gt;&lt;SPAN&gt;execution of any type's class initializer method will not trigger automatic execution of any class initializer methods defined by its base type.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Indeed, why should it?&lt;/SPAN&gt;&lt;/EM&gt;&lt;I&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;The answer to question 2 is complicated.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Constructing instance fields in the most derived class first is the only way to ensure that readonly fields are initialized and then not changed.&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Check out Eric Lippert’s blog for a decent explanation: &lt;A href="http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one.aspx"&gt;&lt;FONT color=#800080&gt;http://blogs.msdn.com/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=57964" width="1" height="1"&gt;</description></item><item><title>Using the Exception Hunter Command Line to find All Methods that throw a given Exception </title><link>http://www.simple-talk.com/community/blogs/jcrease/archive/2008/01/31/45719.aspx</link><pubDate>Thu, 31 Jan 2008 12:01:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:45719</guid><dc:creator>Jason Crease</dc:creator><slash:comments>0</slash:comments><comments>http://www.simple-talk.com/community/blogs/jcrease/comments/45719.aspx</comments><wfw:commentRss>http://www.simple-talk.com/community/blogs/jcrease/commentrss.aspx?PostID=45719</wfw:commentRss><description>&lt;P&gt;Red-Gate's new .NET tool - Exception Hunter - shows you the exceptions that can be thrown by a .NET method. However, many users would like to see this the other way round, i.e. pick an exception and see which methods throw that exception. We will endeavour to put this in the next version of Exception Hunter. &lt;/P&gt;
&lt;P&gt;However, for the moment this functionality is available via the Exception Hunter command line. I've recorded a 5-minute video where I demonstrate how to use the command-line to find all methods that throw IO exceptions in a simple application. Have a look... &lt;/P&gt;
&lt;P&gt;&lt;A href="/blogbits/jason_crease/Exception_Hunter_Command_Line_demo_skin.swf"&gt;http://www.simple-talk.com/blogbits/jason_crease/Exception_Hunter_Command_Line_demo_skin.swf&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;To download the 14-day free-trial of the .NET Developer Bundle, which includes Exception Hunter, go to: &lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.red-gate.com/dynamic/downloads/downloadform.aspx?download=exceptionhunter"&gt;Download .NET Developer Bundle&lt;/A&gt;&lt;/P&gt;&lt;img src="http://www.simple-talk.com/community/aggbug.aspx?PostID=45719" width="1" height="1"&gt;</description></item></channel></rss>
