Bill Blogs in C# -- Effective C#

Bill Blogs in C# -- Effective C#

Created: 10/24/2008 6:37:29 PM

Well, today is being spent getting everything ready for traveling to Los Angeles for the PDC conference.

Like most people without a blue badge, I’m going as an attendee to learn as much as I can about the future of our industry and the platforms I use.  However, there is one known appointment on the schedule:

I’ll be at the PDC bookstore on Tuesday from 12:15 to 12:45 to sign copies of More Effective C#.  If you’re coming to PDC, stop by and say hello.

Created: 10/23/2008 12:58:00 AM

Three different items from More Effective C# have been posted publicly on the InformIT site:

Item 36:  Understand how Query Expressions Map to Method Calls.

Linq is built on two concepts: A query language and a translation from that query language to a set of methods.”

Item 44: Prefer Storing Expression<> to Func<>

If your type will be storing expressions, passing those expressions to other objects not under your control, or if you will be composing expressions into more complex constructs, consider using expressions instead of func. You’ll have a richer set of APIs that will enable you to modify those expressions at runtime, and invoke them after you have examined them for your own internal purposes.

Item 13: Use lock() as your First Choice for Synchronization.

Threads need to communicate with each other. Somehow, you need to provide a safe way for different threads in your application to send and receive data with each other. However, sharing data between threads introduces the potential for data integrity errors in form of synchronization issues. Somehow you need to be certain that the current state of every shared data item is consistent. You achieve this safety by using synchronization primitives to protect access to the shared data. Synchronization primitives ensure that the current thread will not be interrupted until a critical set of operations is completed.

It will give you a taste of the rest of the book.

I hope you enjoy it.

Created: 10/17/2008 9:00:00 PM

Today is the official release date for More Effective C#

Writing a book may seem to be a solitary activity, but nothing could be further from the truth. I have been lucky enough to work with fantastic editors, technical editors, and community members as I have put this together. If you read the acknowledgements, you’ll see what I mean.

Created: 9/4/2006 7:04:23 AM
Not so much a code as what you might call 'guidelines'

Recently, one of the readers of Effective C# asked me some questions about Properties vs. Get and Set methods.  It turned into a rather interesting conversation, so I'm posting it all here:

The original Question:

I'm writing because of a discussion we've been having about the first item in your book. As you know, that item says to "Always use properties instead of accessible data members."

Our main issue is that the book doesn't explain the value of properties over the traditional set/get method approach. In fact, some of the folks on the team are arguing that properties are just syntactic sugar that have more negatives than positives. One example given is that if a property has both set and get implemented then the property could accidentally be assigned when the intention was comparison
        obj.serverDown = false
versus the desired
        obj.serverDown == false
Whereas, with the traditional set/get method, the above bug isn't possible
        ! obj.IsServerDown()

I'm curious what your opinion/rationale is on the topic? Also, do you know of any other
references (online or in print) that discuss this issue?

My first answer:

There are a few reasons why I believe Properties are beneficial vs. the traditional get and set methods used in earlier OO languages (such as C++). 

Consider SOA and a document centric API:

Properties are naturally serialized using the XML serializer. Therefore, a list of employees defined using properties becomes a simple XML document for wire transfer. (I’m assuming read/write properties for Name, Salary, etc).  You can’t easily use the XML serialize for a similar type implement using get / set methods. This is a necessity to build SOA applications where the client will request a document from the server.  The natural document is the set of public properties for a data type. (The same argument can be made for the client code, where a command document is a type with a set of public properties).

Databinding:

This one may be cheating, because one could argue that MS could implement databinding using get / set methods.  But they didn’t, so properties are the clear winner here. And, in fact, if MS did use a get / set metaphor, it would be similar to Java beans, where get_ and set_ denoted a property.  Personally, I dislike the idea that a methods name can give it magical behavior.

Clarity:

Despite the text in the article you reference below, I think there is merit to the property syntax, when used correctly.  It clearly shows that a type contains certain data elements (at least logically, even if not physically).  Point.X looks cleaner to me than Point.get_X(), or Point.set_X(256).  The syntax of the language expresses the design intent more clearly.  That’s certainly subjective, but that’s my opinion.

To address your concern below, there are two answers.  First, it’s much less likely to make the mistake of if (obj.ServerDown = false) because it can only be done with boolean types (not any arbitrary integral type as in C or C++). Secondly, the habit of putting the constant on the left side fixes that as well: if (false == obj.ServerDown).

On the question of hiding inefficiencies behind properties:

Let's consider this code:

public void Calc(int[] foo)
{
  Sum = 0;
  for (int i = 0; i < foo.Length; i++)
    Sum += foo[i];
}

It is indeed possible that the Length property (or the indexer) cause serious inefficiencies.  (Look at the code again, and imagine that Sum is a property with Get and Set accessors.) But, let's not get carried away. In most cases, the JIT compiler will inline simple properties, and there is no inefficiency at all. Of course, you may consider caching the temp variable anyway, and there may be some savings, if the setter has extensive validation.

Syntactically, you could hide anything inside a property's get or set methods.  You could even include database access to retrieve (or set) the value. But, just because it's syntactically correct doesn't mean you should do it.  I’d say it’s a bad practice to hide a database access behind a property for several reasons.  Would you ever make a database call to retrieve one scalar value?  (That’s what such a getter would look like.) Wouldn’t it be far more likely that you would design your application to pull some reasonable set of data from the database and have it locally available?  My point is that I wouldn’t believe GetCommission() makes a database call any more than a SalesPerson.Commission property. And, if the app really does use some form of lazy evaluation, you’re paying the performance hit regardless of the property or method syntax, so it really doesn’t matter.

So, if the argument is that properties are ‘hiding’ performance issues, I don’t think that’s often true.  Most developers would think getSomething() and setSomething() would contain the same code as a Something property. The JIT compiler knows a property is a get / set method pair and can perform the same optimizations as a get / set method pair. So, you really don’t lose anything.  In some sense, properties are syntactic sugar (there’s no new amazing functionality here), but the XML Document serialization and databinding are the two practical reasons to prefer them over get / set methods.  Your colleagues have found the one negative (= vs. ==), which has been around since the dawn of C, so we’ve probably got the habits to handle that one.

After that initial dialogue, the reader and I discussed some guidelines for deciding between properties and methods.  Because, there are performance pitfalls hiding behind properties and indexers, if misused.

Here's what we came up with:

  • Use a Property when all these are true:
    The getters should be simple and thus unlikely to throw exceptions.  Note that this implies no network (or database) access. Either might fail, and therefore would throw an exception.
  • They should not have dependencies on each other.  Note that this would include setting one property and having it affect another.  (For example, setting the FirstName property would affect a read-only FullName property that composed the first name + last name properties implies such a dependency )
  • They should be settable in any order
    The getter does not have an observable side effect Note this guideline doesn't preclude some forms of lazy evaluation in a property.
  • The method must always return immediately. (Note that this precludes a property that makes a database access call, web service call, or other similar operation).
  • Use a method if the member returns an array.
  • Repeated calls to the getter (without intervening code) should return the same value. 
  • Repeated calls to the setter (with the same value) should yield no difference from a single call.
  • The get should not return a reference to internal data structures (See item 23). A method could return a deep copy, and could avoid this issue.



Created: 10/5/2005 6:13:56 AM
Peter is always thorough.

Peter N. Roth reviewed "C# Precisely", and "Effective C#" in the latest issue of C++ Users Journal.

You can read the full review here: http://www.cuj.com/documents/s=9897/cuj0510book/

I'll only add one point:  Peter rightly complains about numerous combined word errors that were introduced in the typesetting process. Those have largely been fixed in the second and subsequent printings. 



Created: 9/26/2005 5:48:31 AM
What comes next?

One of the comments on an earlier entry (http://www.srtsolutions.com/blogs/billwagner/2005/06/21/id93158.aspx) asks if I'm going to write an updated version of Effective C# for version 2.0.

I'm not certain, for two reasons.  First of all, my goal with the content in Effective C# was to ensure that all my recommendations continue to be valid with version 2.0.  By and large, I think that's true. (Some of the boxing and unboxing advice changes with generics, and the garbage collector got some performance improvements.) 

However, there are a lot of new techniques that developers can make use of.  I intend on writing about it.  I'll post announcements as these activities become public.  However, I am working on an outline to cover best practices for C# 2.0, and beyond.



Created: 9/21/2005 6:37:41 AM
For everything else.... Oh, never mind

Cost of PDC:  $1500
Hotel (5 nights): $950
airfare:  $375

Having the C# Product unit manager recommend your own book to you....

Priceless.

<short backstory>

At PDC, a number of RD's were invited to spend some time with members of the C# team to discuss the language, and how we interact with customers.  I mentioned that most of the writing I do is meant to help C# developers learn best practices for working with the C# language, and I was looking for more resources from the team to help.  Scott Wiltamuth's answer had the whole room laughing.

</short backstory>

Hopefully, that means he thought the advice was on point.



Created: 9/10/2005 3:45:34 AM
On immutable structs, structs, and classes

I received the following question that relates to Item 7 in Effective C#. It’s not strictly an errata, so I thought I would post it here for general discussion:

In Item 7, you recommend the use of immutable structs. I am puzzled by why you would recommend structs and not immutable classes. It seems to me that one of the main benefits of immutable objects is that there is no need to copy them; you can pass references to them all around your program without any worries that they might get changed. But structs automatically get copied every time they get passed anywhere. You gain a little bit of efficiency by not having to reference them, but at the price of having to keep making more and more copies of whatever fields your struct has. It seems to me that unless you are concerned about thread safety, you might as well make a struct mutable, because it is going to get copied anyway.

You could, of course, put "ref" on all of the methods that handle your struct, but that seems like you're back to the equivalent of just using immutable reference types, and you've done it in a goofy roundabout way that is liable to confuse somebody else who has to maintain your program.

(There are other reasons I don't like using structs. They look exactly like objects, and they can be passed to methods and such that are expecting objects, which again can lead to some heavy confusion to a maintainance programmer.)

I’ll boil this down to three questions:

1. Why use structs at all?

This is the subject of Item 6. The short answer is that classes support polymorphism, whereas structs do not. (Yes, I’m simplifying. Structs are derived from System.Object, so they do support all the methods from System.Object.) However, removing support for inheritance, virtual functions, and the other tools of object – oriented programming gives you some increased efficiency: All methods are statically bound, which increases the likelihood of inlining. In addition, there are no heap allocations, and no corresponding workload for the garbage collector.

Sometimes you don’t need the extra power of a class, so the simpler tool is the best one.

Your closing comments are all valid: structs do complicate many things in a large program. Because of that I would guess that 95% of the time, I pick a class. That 5% is important and will often make a program more efficient.

2. Why should structs be immutable?

Structs should be immutable because they are simpler. Once created in a valid state, they remain so. It’s also true that a mutable struct probably has a broken GetHashCode() method, but that’s the subject of Item 10. Finally, from a design standpoint, structs usually represent a single datum: something that is replaced as a whole, rather than modified. Immutability would support that.

3. Why not use immutable classes?

I never said not to use immutable classes. In fact, immutable classes are worth creating for many of the same reasons as immutable structs: they are simpler to code, their validity is easier to enforce, side-effects are less likely to introduce bugs, and the list goes on.

But, at some point, your program modifies its state. So, an item dedicated to creating immutable classes would be saying “use immutable classes, except when program efficiency means that creating a copy would be way too slow”. In many cases, that can be re-stated as “if you can support immutability for this type efficiently, it’s likely to be a good candidate for a struct.”



Created: 6/30/2005 7:07:23 AM
A very thorough review of Effective C#
Jim Holmes, who runs the Dayton Ohio .NET User group posted a very thorough review of Effective C# yesterday.  (Thank you, Jim). 

The slashdot Review
More than 150 comments, and growing
Jim's follow-up comments
After seeing the response on SlashDot
The Dayton Ohio .NET User Group
You know, if you're in the Dayton area.
Created: 6/21/2005 8:27:42 PM
There's no hidden meaning, really.

A friend asked me why there is a violin on the cover of Effective C# instead of any other instrument.

 Effective C# Cover

The logic was actually pretty simple.  A musical instrument seemed logical for a C# book. At the time, four of the five members of my family played some instrument. I play guitar, my wife plays piano, Lara plays flute, and Sarah plays violin. (Scott has started playing the trumpet now, but that predates the book). 

The piano makes a silly cover. The guitar seemed wrong, and a flute on the book cover looked a bit silly. So violin won by default.

Sort of like software design:  Throw out all the lousy ideas, and the one that's left is probably pretty good.  At least I hope so.



Created: 6/9/2005 12:19:06 AM
An Effective C# reader had a number of questions on Exceptions and Remoting

Throwing Exceptions across appdomain boundaries is more complicated than it is in other situations.



The full discussion
It's in my Effective C# blog, because it centers on book items
Created: 5/18/2005 3:37:04 PM
A reader asks about a variation of loop variable hoisting

Question on Item 11.

Regarding your examples of loops, where would the following end up in efficiency?

// Loop 4: (

for ( int index = 0, len = foo.Length;  index < len; index++)

This is how I used to do it in Java (I wonder if I didn’t actually learn it from “Effective Java”). Now I use foreach, but am still interested in your insight on which of loop 2 or 3 this resembles and how efficient it is.

Answer:

The core point of Item 11 is not that one particular looping construct is so much faster than any other. Rather, it is that the performance differences between different constructs are just not that large. You should instead pick the construct that creates the most readable and most maintainable code. Following on that advice, the product teams are working on optimizing the most readable constructs, rather than less common and less readable constructs.

My own tests on your construct bear that out. The version you have exhibits the same performance penalty that I mentioned in Item 11 of Effective C# regarding loop variable hoisting. My timings showed this to be the slowest of the looping constructs I mentioned there.

The moral of the story is this: Write the clearest code you can, and optimize these low-level constructs only after running performance tests.



Effective C# Errata page
Those mistakes readers have found
Effective C# Homepage
Learn more about the book
Created: 3/18/2005 6:13:30 AM
It's in the stores only, if you are in their region.
Books a million (http://www.booksamillion.com) has a promotional deal running on Effective C#. It's in the stores only, so the website does not mention the promo.

The Effective C# page at Books a Million
If they update it with the promotion
Created: 2/23/2005 10:00:12 PM
Those of you that receive .NET Insight saw this yesterday

Fawacette Technical Publications (FTP) has published a second excerpt from Effective C# online. This time it's Item 44, discussing how to create your own custom exception classes.



The landing page at FTP
This is where you can retrieve both excerpts
The Effective C# Home page
Addison Wesley's page on Effective C#.

Created: 1/11/2005 9:07:02 PM
I've opened a blog for reader Q & A (and errata *sigh*).

I’ve added the first reader Q & A item to the Effective C# book blog:

In the section on Conditionals you say that in order to create a method that will fire if more than one condition is true (logical AND), you need to use

#if (VAR1 && VAR2)

#define BOTH

#endif

However, it is possible to chain the conditionals together (according to MSDN, anyway…)

<QUOTE from=”MSDN”>

[Conditional("A")] public static void IfAandB( )

{

   AandBPrivate( );

}

[Conditional("B")] static void AandBPrivate( )

{

   /* Code to execute when both A and B are defined... */

}

Call IfAandB; if both A and B are defined, AandBPrivate will execute.

</QUOTE>

Is there any reason to use your method above the MS one? 

You can read the full answer here:



The Effective C# Book Blog
Discussions on Effective C#
The Effective C# Book Blog RSS Feed
Subscribe for news and information
The first question
Conditional attributes

Current Projects

I create content for .NET Core. My work appears in the .NET Core documentation site. I'm primarily responsible for the section that will help you learn C#.

All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.

I'm also the president of Humanitarian Toolbox. We build Open Source software that supports Humanitarian Disaster Relief efforts. We'd appreciate any help you can give to our projects. Look at our GitHub home page to see a list of our current projects. See what interests you, and dive in.

Or, if you have a group of volunteers, talk to us about hosting a codeathon event.