There are quite a many gems hidden in C# and .NET Framework. Here are some:
C# 2 introduced the concept of nullable value types. If you assign a nullable value type to a non-nullable variable and if the former is null, you will get a runtime error. Meet ?? operator, also known as null-coalescing operator. The operator simply returns a default value when the nullable value type is null otherwise the actual value itself. You can think of it as a specialized ternary operator for nullable-value types.
Again, C# 2 introduced the concept of partial classes, primarily to separate designer-generated code from user-written code so that the designer (Visual Studio’s) can regenerate the code without affecting user’s part. There is one side-benefit too: multiple developers can work on the same class split across multiple files. C# 3 introduced partial methods as an evolvement of partial classes. In short, partial method is one that is declared (without body) but its actual implementation is left to the developer and the implementation is optional. The former aspect may look very similar to abstract methods but the latter is how partial methods differ from abstract methods.
Say you are implementing a business component that performs complex processing. At key stages of this process you want to give the developer an option to do detailed logging or tracing on how the actual logic is running or monitor the code’s performance. In order to do this, you can interleave logging method calls but you do not care how the actual logging is done, if at all it is done. Here is a sample of how the business component class may look like:
The MortgageCore class defines a partial method named TraceMessage which is actually implemented in the subsequent partial class definition. The following shows the reverse-engineered definition of the MortgageCore.IsMortgateRequestValid() method from the compiled output:
Without the partial method implementation, the method looks like:
As you can see, the compiler has removed all the invocations to the partial method after the partial method implementation has been removed. Partial methods may look like delegates too: unless any handlers are hooked, calling a delegate doesn’t have any effect, which is similar to partial method behavior. But again, the C# complier hard-wires delegate calls into assembly while empty partial methods are optimized away without leaving any traces of their existence. Keep in mind the following:
- They can only exist inside a partial class
- They are implicitly private
- No multiple definitions for partial methods
- Can accept parameters including ref types but not out types
- Cannot have a return type; only void
As you might have probably guessed, most of the restrictions are due to the fact that the complier removes partial method references if they are not defined.
Quite popular in dynamic languages like Ruby, duck typing allows the C# compiler to treat a type with characteristics of another type like that type itself (confusing, I know! :-)). Take a look at the sample below:
The class DuckType doesn’t implement
IEnumerator but has members with the same name as that of those interfaces. This lets the DuckType class to be treated like one that actually implemented these two interfaces and hence can be used in
Produces the output:
Well, I have a laundry list of items to cover under this topic and so it might become a multi-part series.