Introduction
Welcome to this installment of the .NET Nuts & Bolts column! When it comes to tips and tricks there are many items that can be considered. For this article we'll briefly recap the C# 4.0 language features, cover some tips, tricks, and reminders, and touch on a couple of useful tools.
C# 4.0 Overview
C# 4.0 contains four primary areas of emphasis.
- Dynamically typed objects
- Optional and named parameters
- Improved COM interoperability
- Co- and contra-variance
The last .NET Nuts and Bolts article covered named and optional parameters and covered how it is responsible for some of the improved COM interoperability when interacting with DLLs such as the Office integration components. While named and optional parameters are available in C# programming now, it is important to establish ground rules for responsible use. The following table outlines considerations for when to use each.
<TABLE ALIGN="center" BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="100%"> <TR> <TD VALIGN="top"> <P><B>When to consider overloading:</B></p> <UL> <LI>When defaults are not compile-time constants</LI> <LI>When alternatives specify different types</LI> </UL> </TD> <TD valign="top"> <P><B>When to consider optional parameters:</B></P> <UL> <LI>When you only need to specify default values for the optionals, especially if there are a number of optionals</LI> </UL> </TD> </TR> </TABLE>
Extension Methods
Extension methods allow you to add new functionality on existing types. This ability even includes the ability to add new functionality to sealed classes. They are declared like static methods and called like instance methods. They are scoped by using clauses and are valid for interfaces and constructed types. The following code example demonstrates adding two methods to the decimal type from the .NET Framework.
static class ExtensionSample { public static decimal Triple( this decimal d ) { return d*3; } public static decimal Half( this decimal d ) { return d / 2; } } decimal y = 14M; y = y.Triple().Half();
When building extension methods within your code base it is recommended to consider a separate namespace to allow them to be optional. It is also best you not be mean to others by applying to all objects by extending object. The following sample demonstrates what not to do as it alters the default behavior of all classes. Normally accessing a property or method on an object that is null a NullReferenceException
would be generated. The extension method below would add a .IsNull()
method that would alter that behavior, which then makes your code behave different from the default behavior expected from the .NET Framework
. The following sample code demonstrates what not to do:
namespace System { public static class MyExtensions { public static bool IsNull(this object o) { return o == null; } } } while (!myObject.IsNull()) { … }
Obsolete Code
If you've been using the .NET Framework
for a number of years chances are you've seen the Framework versions advance and seen instances where some of the .NET Framework classes such as prior Configuration
classes have gone obsolete and you've received warnings from the compiler about it to make you aware. You may have wondered how to do that same thing with your own code. There is an Obsolete
attribute that you can use to decorate your own classes and methods to indicate they are being phased out as well. If you're working independently of others, then chances are you won't need it. However, in working with a project team where you may have implemented a framework, helper classes or other conventions, it can be very helpful to use the Obsolete
attribute to flag dead code that won't be used going forward. This allows them to be migrated over time rather than just deleting from your code. This is very handy as you refactor code to communicate through the compiler that a particular item is obsolete. By default the items are served up as warnings, but an optional flag can indicate if they should be treated as warnings. It is worthwhile to have that setting be a configuration value so that you can enable or disable it across the board.
// Include message for compiler to present [Obsolete("This class is dead. It has been replaced by MyClass3.")] class MyClass1 { // ... } // Include message and generate a compiler error [Obsolete("This class is dead. It has been replaced by MyClass4. "), true] class MyClass2 { // ... }
Garbage Collection
If you are programming in .NET 3.5 or before you can force garbage collection through GC.Collect()
, but it is heavily advised that you do not use it unless you really know what you are doing. It is very likely you'll outguess the garbage collection system and do more harm than good. With the release of the .NET Framework 4.0
there are new garbage collection options and ways to control the behavior, which does make it more feasible to trigger and control. (Note: this will likely be a future article).
Using Keyword
The using keyword has multiple uses. One lesser known is it can be used to provide automatic cleanup of disposable types. The compiler translates it in to try...finally
behavior. I highly recommend using it whenever using IDataReader
or the LINQ to Entity
data context to retrieve data from the database. The following sample code demonstrates a simple implementation where a DataReader
is wrapped in a using statement to ensure it is disposed when its use is out of scope.
using (IDataReader reader = provider.ExecuteReader(dataCmd)) { // … }
LINQ to Entities
In past articles I've covered LINQ to SQL and more recently LINQ to Entities. I wanted to offer some clarification on when to use either. Predominantly for any new development it should be LINQ to Entities. It contains a superset of LINQ to SQL. Microsoft is continuing to advance and provide more features for LINQ to Entities and does not have plans to make any advancements to LINQ to SQL.
<TABLE ALIGN="center" BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="100%"> <TR> <TD VALIGN="top"> <P>When to consider LINQ to Entities:</P> <UL> <LI>Fashioned after ORM where you have an object structure that is abstracted from the physical database</LI> <LI>Not targeting SQL Server</LI> <LI>New development</LI> </UL> </TD> <TD valign="top"> <P>When to consider LINQ to SQL:</P> <UL> <LI>You are already using it</LI> <LI>Targeting SQL Server and a 1:1 relationship between model and database</LI> </UL> </TD> </TR> </TABLE>
Parallel For
Historically Moore's law has allowed our applications to run faster and faster without additional effort on our part as processors increase in speed. Now that speed growth is fairly flat and the trend is towards multiple core and multiple processors. In order to take advantage of multiple processors you need to think about running steps in parallel instead of sequentially. Think of it similar to threading and running multiple threads, but the difference being they are also executing across different processors simultaneously. Microsoft released some items in the language as well as in Microsoft Visual Studio that allows you to do more parallel programming and split tasks between processors. Just because it is available and can be faster doesn't mean that everything should be done in parallel. Often times you can get different results depending upon the problem you are solving. The following sample code shows the use of a Parellel.For
loop in order to read text files in parallel since they are not needed sequentially
foreach(string file in inputFiles) { string content = File.ReadAllText(file); Parallel.Invoke( () => CountCharacters(content), () => CountWords(content) ); }
Compiling
This is a very simple tip and should go without saying, but unfortunately gets overlooked time and time again. Compiling is not the same as testing no matter how much of a hurry you are in or how small of a change you've made. If you don't believe me, build an email application that involves a loop. Almost every time I've seen that done the developer didn't test thoroughly and had the loop go awry and SPAM a whole bunch of unsuspecting recipients. Additionally, the first time a system is tested with two or more concurrent users should not be when it goes in to production. Folks can get lazy and execute the same tests time and time again. It is important to test from multiple perspectives as well as concurrent use.
Tools: XSD2Code
XSD2Code is a tool that will generate .NET classes
based on a given XSD schema. It makes the XSD schema in to strongly typed objects, which makes them easier to work with. As an example of use, my company has an application for filing taxes for non-profit firms. We collect all of the data necessary and then put it in the XML format dictated by the IRS. We used XSD2Code to generate strongly typed objects from the IRS schema and make it easier to build the XML necessary for electronic filing.
Tools: LINQPad and LINQKit
If you are doing LINQ development LINQPad and LINQKit can be your best friends. LINQPad is a tool that allows interactive query of databases using LINQ. You can drop code snippets in to the tool that will execute and show results. This helps test out LINQ statements in advance of fully building them in code. As a byproduct of how it operates it can be used for more than just a LINQ tool. It can also be used to evaluate any C# expression or statement block. You can point it to your development environment and LINQ away.
LINQKit is a companion tool to LINQPad and can be used with it. LINQKit helps in the process of building dynamic LINQ expressions.
Tools: 7Zip
7Zip is a file archive tool with a high compression ratio. It can be used in desktop form for zipping and unzipping files as well as with an SDK to bring similar compress and uncompress functionality to the .NET framework. I believe .NET had a namespace for helping with compressed files, but 7Zip does a phenomenal job with the compression.
Tools: CodePlex
Most folks seem to know about CodePlex, but forget over time. It is a great place to find and share resources. There is an amazing amount of stuff available.
- NerdDinner for ASP.NET MVC
- XSD2Code
- RSSToolkit
- AJAX Control Toolkit
- Team Foundation Server Admin Tool
- Windows Azure Guidance
- Many, many, many, more...
Summary
We have covered a variety of C# related topics. Many of them have been covered in depth in past .NET Nuts and Bolts articles, However, this added a twist of advice and suggestions on each of them. Please feel free to share additional tips and tricks with me that you'd like to see included in a future article.
Future Columns
The topic of the next column is yet to be determined. If you have something else in particular that you would like to see explained here you could reach me at through http://markstrawmyer.com/.
Related Articles
- Optional and Named Parameters in C# Programming
- Working with Object Context in the Entity Framework
- Joins and UI Binding with the Entity Framework
转载:http://www.codeguru.com/csharp/csharp/cs_misc/article.php/c17299/C-Programming-Tips-and-Tricks.htm