Saturday, December 29, 2012

Pro C# and the .NET4 platform

Descendents of ValueType are automatically allocated on the stack and therefore have a very predictable lifetime and are quite efficient. A reference type is an object allocated on the garbage-collected managed heap. By default, when you perform a test for equality on reference types (via the C# == and !=operators), you will be returned true if the references are pointing to the same object in memory. However, even though the string data type is indeed a reference type, the equality operators have been redefined to compare the values of string objects, not the object in memory to which they refer. We are able to test for equality using the Equals() method of String as well as the baked-in equality operators.
The benefit of invoking the default constructor of a structure is that each piece of field data is automatically set to its default value.
When you assign one value type to another, a member-by-member copy of the field data is achieved. In stark contrast to value types, when you apply the assignment operator to reference types (meaning all class instances), you are redirecting what the reference variable points to in memory. By default, when a value type contains other reference types, assignment results in a copy of the references.
If a reference type is passed by reference, the callee may change the values of the object’s state data as well as the object it is referencing. If a reference type is passed by value, the callee may change the values of the object’s state data but not the object it is referencing.
C# allows you to define a static constructor, which allows you to safely set the values of your static data. A given class may define only a single static constructor. In other words, the static constructor cannot be overloaded. A static constructor does not take an access modifier and cannot take any parameters. The runtime invokes the static constructor when it creates an instance of the class or before accessing the first static member invoked by the caller. The static constructor executes before any instance-level constructors.
It is also possible to apply the static keyword directly on the class level. When a class has been defined as static, it is not creatable using the new keyword, and it can contain only members or fields marked with the static keyword.
Private items can only be accessed by the class (or structure) that defines the item.
Protected items can be used by the class which defines it, and any child class. However, protected items cannot be accessed from the outside world using the C# dot operator.
Internal items are accessible only within the current assembly. Therefore, if you define a set of internal types within a .NET class library, other assemblies are not able to make use of them.
When the protected and internal keywords are combined on an item, the item is accessible within the defining assembly, the defining class, and by derived classes.
By default, type members are implicitly private while types are implicitly internal.
Non nested types can only be defined with the public or internal modifiers.
Although you can encapsulate a piece of field data using traditional get and set methods, .NET languages prefer to enforce data encapsulation state data using properties.
The .NET base class libraries always favour type properties over traditional accessor and mutator methods when encapsulating field data. Therefore, if you wish to build custom classes that integrate well with the .NET platform, avoid defining traditional get and set methods.
When you are defining an automatic property, it must support both read and write functionality. However, it is possible to implement an automatic property which defines a more restrictive get or set.
class Garage
{
// The hidden int backing field is set to zero!
public int NumberOfCars { get; set; }
// The hidden Car backing field is set to null!
public Car MyAuto { get; set; }
}
// Here, the default constructor is called implicitly.
Point finalPoint = new Point { X = 30, Y = 30 };
// Here, the default constructor is called explicitly.
Point finalPoint = new Point() { X = 30, Y = 30 };
Constant fields of a class are implicitly static. Like a constant, a read-only field cannot be changed after the initial assignment. However, unlike a constant, the value assigned to a read-only field can be determined at runtime, and therefore can legally be assigned within the scope of a constructor, but nowhere else. Unlike a constant field, read-only fields are not implicitly static. Thus, if you wish to expose PI from the class level, you must explicitly make use of the static keyword. If you know the value of a static read-only field at compile time, the initial assignment looks very similar to that of a constant.
C# supplies another keyword, sealed, that prevents inheritance from occurring. When you mark a class as sealed, the compiler will not allow you to derive from this type. Structures are always implicitly sealed.
If a base class wishes to define a method that may be (but does not have to be) overridden by a subclass, it must mark the method with the virtual keyword.
When a subclass wishes to change the implementation details of a virtual method, it does so using the override keyword. You can also apply the new keyword to any member type inherited from a base class (field, constant, static member, or property).
// Use 'as' to test compatability.
Hexagon hex2 = frank as Hexagon;
if (hex2 == null)
Console.WriteLine("Sorry, frank is not a Hexagon...");
In addition to the as keyword, the C# language provides the is keyword to determine whether two items are compatible. Unlike the as keyword, however, the is keyword returns false, rather than a null reference, if the types are incompatible.
// Use a comma-delimited list to declare multiple objects to dispose.
using(MyResourceWrapper rw = new MyResourceWrapper(),
rw2 = new MyResourceWrapper())
{
// Use rw and rw2 objects.
}
A Formalized Disposal Pattern
With the release of .NET 4.0, the base class libraries provide a very interesting generic class named Lazy<>, defined in the System namespace of mscorlib.dll. This class allows you to define data that will not be created unless your code base actually makes use of it.
private Lazy<AllTracks> allSongs = new Lazy<AllTracks>();
The yield keyword is used to specify the value (or values) to be returned to the caller’s foreach construct.

Visual Studio 2010 can only be used to build single file assemblies. In the rare case that you need to
build a multi-file assembly, you must make use of command-line tools.
The entity that compiles CIL code into meaningful CPU
instructions is a JIT compiler, which sometimes goes by the friendly name of Jitter.
Once you find the snippet you want to activate, press the Tab key twice.


TO:
Chapter 10 Understanding Generics

No comments:

Post a Comment