Saturday, July 4, 2015

C# in Nutshell Chapter 13 - Diagnostics and Code Contracts

Conditional Attribute

The Conditional attribute instructs the compiler to ignore any calls to a particular class or method, if the specified symbol has not been defined.

 static void Main()
        {
            WriteLine();
            Console.ReadLine();
        }

        [Conditional("TESTMODE")]
        public static void WriteLine() { Console.WriteLine("HelloWorld"); }


In Visual Stuido project property -> Build -> Optional compiling symbol to set it

The Conditional attribute is ignored at runtime—it’s purely an instruction to the compiler.

Debug and Trace Classes


Code Contracts

public static bool AddIfNotPresent<T> (IList<T> list, T item)
{
Contract.Requires (list != null); // Precondition
Contract.Requires (!list.IsReadOnly); // Precondition
Contract.Ensures (list.Contains (item)); // Postcondition
if (list.Contains(item)) return false;
list.Add (item);
return true;
}

The preconditions are defined by Contract.Requires and are verified when the method starts. The postcondition is defined by Contract.Ensures and is verified not where it appears in the code, but when the method exits. Preconditions and postconditions act like assertions and, in this case, detect the following errors:
  • A bug in the method whereby we forgot to add the item to the list
  • A bug in the method whereby we forgot to add the item to the list
Preconditions and postconditions must appear at the start of the method. 


Windows Eventlog

To write to a Windows event log:
1. Choose one of the three event logs (usually Application).
2. Decide on a source name and create it if necessary.
3. Call EventLog.WriteEntry with the log name, source name, and message data.

The source name is an easily identifiable name for your application. You must register a source name before you use it—the CreateEventSource method performs this function. You can then call WriteEntry :
const string SourceName = "MyCompany.WidgetServer";
// CreateEventSource requires administrative permissions, so this would
// typically be done in application setup.
if (!EventLog.SourceExists (SourceName))
EventLog.CreateEventSource (SourceName, "Application");
EventLog.WriteEntry (SourceName, "Service started; using configuration file=...", EventLogEntryType.Information);


The Stopwatch Class

The Elapsed property returns the elapsed interval as a TimeSpan :

Stopwatch s = Stopwatch.StartNew();
System.IO.File.WriteAllText ("test.txt", new string ('*', 30000000));
Console.WriteLine (s.Elapsed); // 00:00:01.4322661










































C# in Nutshell Chapter 8 - LINQ

LINQ

A query operator never alters the input sequence; instead, it returns a new sequence. This is consistent with the functional programming paradigm, from which LINQ was inspired.

string[] s = {"Dirk", "Xi", "Auli", "Jouni"};
IEnumerable<string> items = s.where (n => n.length >=4);


Sequence Operators 
s.OrderBy()
s.Select()
s.Take()
s.Skip()
s.Reverse()

Element Operators
s.First()
s.Last()
s.ElementAt()

Aggregation Operators
s.Count();
s.Min();

Quantifiers (return a bool)
s.Contains()
s.Any()\

Other Operators

int[] seq1 = { 1, 2, 3 };
int[] seq2 = { 3, 4, 5 };
IEnumerable<int> concat = seq1.Concat (seq2); // { 1, 2, 3, 3, 4, 5 }
IEnumerable<int> union = seq1.Union (seq2); // { 1, 2, 3, 4, 5 }


Query Expression

Query expressions always start with a from clause and end with either a select or
group clause. The from clause declares a range variable (in this case, n), which you
can think of as traversing the input sequence—rather like foreach.

IEnumerable<string> query =
from n in names
where n.Contains ("a") // Filter elements
orderby n.Length // Sort elements
select n.ToUpper(); // Translate each element (project)


The Into Keyword

The into keyword lets you “continue” a query after a projection and is a shortcut
for progressively querying.
The only place you can use into is after a select or group clause. into “restarts” a
query, allowing you to introduce fresh where, orderby, and select clauses.

IEnumerable<string> query =
from n in names
select n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")
into noVowel
where noVowel.Length > 2 orderby noVowel select noVowel;

Otherwise, we need to write

IEnumerable<string> query =
from n in names
select n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "");
query = from n in query where n.Length > 2 orderby n select n;


Scoping rules
All range variables are out of scope following an into keyword. The following will not compile:
var query =
from n1 in names
select n1.ToUpper()
into n2 // Only n2 is visible from here on.
where n1.Contains ("x") // Illegal: n1 is not in scope.
select n2;


Projection Strategies

Object Initializers

class TempProjectionItem
{
public string Original; // Original name
public string Vowelless; // Vowel-stripped name
}

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<TempProjectionItem> temp =
from n in names select new TempProjectionItem
{
Original = n,
Vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")
};


Anonymous Types
We can eliminate the TempProjectionItem class in our previous
example with anonymous types:

var intermediate = from n in names
select new
{
Original = n,
Vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")
};
IEnumerable<string> query = from item in intermediate
where item.Vowelless.Length > 2
select item.Original;


Let Keyword

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> query =
from n in names
let vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "") .Replace ("o", "").Replace ("u", "")
where vowelless.Length > 2 orderby vowelless
select n; // Thanks to let, n is still in scope.


Interpreted Queries

LINQ provides two parallel architectures: local queries for local object collections, and interpreted queries for remote data sources.

Interpreted queries operate over sequences that implement IQueryable<T>.


combined interpreted and local queries























Friday, July 3, 2015

C# in Nutshell Chapter 7 - Collections

Enumerator and Enumerable

IEnumerable can be thought of as “IEnumeratorProvider”
string s = "Hello";
// Because string implements IEnumerable, we can call GetEnumerator():
IEnumerator rator = s.GetEnumerator();
while (rator.MoveNext())
{
char c = (char) rator.Current;
Console.Write (c + ".");
}
// Output: H.e.l.l.o.

Fortunately, you rarely need to write this sort of code, thanks to the foreach statement.


IEnumerable<T> (and IEnumerable)
Provides minimum functionality (enumeration only)

ICollection<T> (and ICollection)
Provides medium functionality (e.g., the Count property)

IList <T>/IDictionary <K,V> and their nongeneric versions
Provide maximum functionality (including “random” access by index/key)


ICollection<T> and ICollection

ICollection<T> is the standard interface for countable collections of objects. 

It provides the ability to determine the size of a collection (Count), determine whether an item exists in the collection (Contains), copy the collection into an array (ToArray), and determine whether the collection is read-only (IsReadOnly). For writable collections, you can also Add, Remove, and Clear items from the collection. And since it extends IEnumerable<T>, it can also be traversed via the foreach statement.

The nongeneric ICollection is similar in providing a countable collection, but doesn’t provide functionality for altering the list or checking for element membership:


IList<T> and IList

IList<T> is the standard interface for collections indexable by position.

In addition to the functionality inherited from ICollection<T> and IEnumerable<T>, it provides the ability to read or write an element by position (via an indexer) and insert/remove by position:

IReadOnlyList<T>

In order to interoperate with read-only Windows Runtime collections, Framework 4.5 introduces a new collection interface called IReadOnlyList<T>.











































C# in Nutshell Chapter 6 - Framework Fundamentals

String

The static string.IsNullOrEmpty method is a useful shortcut for testing whether a given string is either null or empty.

string empty = string.Empty
"abc".Contains("a")
"abc".EndsWith("a")
"abc".IndexOf("a")  // return 0;
"abcdef".StartsWith ("abc", StringComparison.InvariantCultureIgnoreCase)
"abcde".IndexOf ("CD", StringComparison.CurrentCultureIgnoreCase); // 2

LastIndexOf is like IndexOf, but works backward through the string.

IndexOfAny returns the first matching position of any one of a set of characters

Console.Write ("ab,cd ef".IndexOfAny (new char[] {' ', ','} )); // 2
Console.Write ("pas5w0rd".IndexOfAny ("0123456789".ToCharArray() )); // 3

LastIndexOfAny does the same in the reverse direction.

Manipulating strings

string left3 = "12345".Substring (0, 3); // left3 = "123";
string mid3 = "12345".Substring (1, 3); // mid3 = "234";
string end3 = "12345".Substring (2); // end3 = "345";

string s1 = "helloworld".Insert (5, ", "); // s1 = "hello, world"
string s2 = s1.Remove (5, 2); // s2 = "helloworld";

PadLeft and PadRight pad a string to a given length with a specified character (or a space if unspecified). If the input string is longer than the padding length, the original string is returned
unchanged.

Console.WriteLine ("12345".PadLeft (9, '*')); // ****12345
Console.WriteLine ("12345".PadLeft (9)); // 12345

TrimStart and TrimEnd remove specified characters from the beginning or end of a string; Trim does both. By default, these functions remove whitespace characters (including spaces, tabs, new lines, and Unicode variations of these): 

Console.WriteLine (" abc \t\r\n ".Trim().Length); // 3

Replace replaces all (non-overlapping) occurrences of a particular character or substring:

Console.WriteLine ("to be done".Replace (" ", " | ") ); // to | be | done
Console.WriteLine ("to be done".Replace (" ", "") ); // tobedone

ToUpper() ToLower() ToUpperInvariant() ToLowerInvariant()


string[] words = "The quick brown fox".Split();
string together = string.Join (" ", words); // The static Join method does the reverse of Split

The static Concat method is similar to Join but accepts only a params string array and applies no separator. Concat is exactly equivalent to the + operator.

string sentence = string.Concat ("The", " quick", " brown", " fox");
string sameSentence = "The" + " quick" + " brown" + " fox";

string.Format

string composite = "It's {0} degrees in {1} on this {2} morning";
string s = string.Format (composite, 35, "Perth", DateTime.Now.DayOfWeek);
// s == "It's 35 degrees in Perth on this Friday morning"

Each number in curly braces is called a format item. The number corresponds to the argument position and is optionally followed by:
  • A comma and a minimum width to apply
  • A colon and a format string
The minimum width is useful for aligning columns. If the value is negative, the data is left-aligned; otherwise, it’s right-aligned. For example:

string composite = "Name={0,-20} Credit Limit={1,15:C}";
Console.WriteLine (string.Format (composite, "Mary", 500));
Console.WriteLine (string.Format (composite, "Elizabeth", 20000));


The equivalent without using string.Format is this:
string s = "Name=" + "Mary".PadRight (20) + " Credit Limit=" + 500.ToString ("C").PadLeft (15);

Comparing Strings

There are two basic algorithms for string comparison: ordinal and culture-sensitive. Ordinal comparisons interpret characters simply as numbers (according to their numeric Unicode value); culture-sensitive comparisons interpret characters with reference to a particular alphabet. There are two special cultures: the “current culture,” which is based on settings picked up from the computer’s control panel, and the “invariant culture,” which is the same on every computer (and closely matches
American culture).

Despite ordinal’s limitations, string’s == operator always performs ordinal case sensitive comparison.The same goes for the instance version of string.Equals when called without arguments; this defines the “default” equality comparison behavior for the string type.

The following methods allow culture-aware or case-insensitive comparisons:
  • public bool Equals(string value, StringComparison comparisonType);
  • public static bool Equals (string a, string b, StringComparison comparisonType);

The static version is advantageous in that it still works if one or both of the strings are null. StringComparison is an enum defined as follows:

public enum StringComparison
{
CurrentCulture, // Case-sensitive
CurrentCultureIgnoreCase,
InvariantCulture, // Case-sensitive
InvariantCultureIgnoreCase,
Ordinal, // Case-sensitive
OrdinalIgnoreCase
}

String order comparison

String’s CompareTo instance method performs culture-sensitive, case-sensitive order comparison. Unlike the == operator, CompareTo does not use ordinal comparison: for ordering, a culture-sensitive algorithm is much more useful. Here’s the method’s definition:

public int CompareTo (string strB);

For other kinds of comparison, you can call the static Compare and CompareOrdinal
methods:
  1. public static int Compare (string strA, string strB, StringComparison comparisonType);
  2. public static int Compare (string strA, string strB, bool ignoreCase, CultureInfo culture);
  3. public static int Compare (string strA, string strB, bool ignoreCase);
  4. public static int CompareOrdinal (string strA, string strB);

Console.WriteLine ("Boston".CompareTo ("Austin")); // 1
Console.WriteLine ("Boston".CompareTo ("Boston")); // 0
Console.WriteLine ("Boston".CompareTo ("Chicago")); // −1
Console.WriteLine ("ṻ".CompareTo ("ǖ")); // 0
Console.WriteLine ("foo".CompareTo ("FOO")); // −1

By supplying a CultureInfo object, you can plug in any alphabet:
// CultureInfo is defined in the System.Globalization namespace

CultureInfo german = CultureInfo.GetCultureInfo ("de-DE");
int i = string.Compare ("Müller", "Muller", false, german);


StringBuilder

The StringBuilder class (System.Text namespace) represents a mutable (editable) string. With a StringBuilder, you can Append, Insert, Remove, and Replace substrings without replacing the whole StringBuilder.

StringBuilder’s constructor optionally accepts an initial string value, as well as a starting size for its internal capacity (default is 16 characters). If you go above this, StringBuilder automatically resizes its internal structures to accommodate (at a slight performance cost) up to its maximum capacity (default is int.MaxValue). A popular use of StringBuilder is to build up a long string by repeatedly calling Append.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 50; i++) sb.Append (i + ",");
Console.WriteLine (sb.ToString())

In our example above, the expression i + "," means that we’re still repeatedly concatenating strings. However, this incurs only a small performance cost in that the strings in question are small
and don’t grow with each loop iteration. For maximum performance, however, we could change the loop body to this: { sb.Append (i.ToString()); sb.Append (","); }

Methods: AppendLine, AppendFormat, Remove, Insert, Replace


Encoding object


Encoding utf8 = Encoding.GetEncoding ("utf-8");

Encoding chinese = Encoding.GetEncoding ("GB18030");

The most common encodings can also be obtained through dedicated static prop-
erties on Encoding:

  1. Encoding.UTF8
  2. Encoding.Unicode
  3. Encoding.UTF32
  4. Encoding.ASCII
Encoding.GetEncodings()


foreach (EncodingInfo info in Encoding.GetEncodings())
    Console.WriteLine (info.Name);

Dates and Times

TimeSpan

A TimeSpan represents an interval of time—or a time of the day

Constructors:

  1. public TimeSpan (int hours, int minutes, int seconds);
  2. public TimeSpan (int days, int hours, int minutes, int seconds);
  3. public TimeSpan (int days, int hours, int minutes, int seconds, int milliseconds);
  4. public TimeSpan (long ticks);  // Each tick = 100ns
Or more convenient to use static From... method:

  • public static TimeSpan FromDays (double value);
  • public static TimeSpan FromHours (double value);
  • public static TimeSpan FromMinutes (double value);
  • public static TimeSpan FromSeconds (double value);
  • public static TimeSpan FromMilliseconds (double value);
For example:
Console.WriteLine (new TimeSpan (2, 30, 0));   // 02:30:00
Console.WriteLine (TimeSpan.FromHours (2.5));  // 02:30:00
Console.WriteLine (TimeSpan.FromHours (−2.5)); // −02:30:00


TimeSpan overloads the + and - operators:

TimeSpan.FromHours(2) + TimeSpan.FromMinutes(30);
TimeSpan.FromDays(10) - TimeSpan.FromSeconds(1);  // 9.23:59:59

TimeSpan can also be used to represent the time of the day (the elapsed time since midnight). To obtain the current time of day, call DateTime.Now.TimeOfDay .


DateTime and DateTimeOffset

A DateTime incorporates a three-state flag indicating whether the DateTime is relative to:
  • The local time on the current computer
  • UTC (the modern equivalent of Greenwich Mean Time)
  • Unspecified
A DateTimeOffset is more specific—it stores the offset from UTC as a TimeSpan:

July 01 2007 03:00:00 −06:00


This influences equality comparisons, which is the main factor in choosing between DateTime and DateTimeOffset. Specifically:
  • DateTime ignores the three-state flag in comparisons and considers two values equal if they have the same year, month, day, hour, minute, and so on.
  • DateTimeOffset considers two values equal if they refer to the same point in time.
DateTime dt1 = new DateTime (2000, 1, 1, 10, 20, 30, DateTimeKind.Local);
DateTime dt2 = new DateTime (2000, 1, 1, 10, 20, 30, DateTimeKind.Utc);
Console.WriteLine (dt1 == dt2);
DateTime local = DateTime.Now; // True
DateTime utc = local.ToUniversalTime();
Console.WriteLine (local == utc); // False



DateTime considers the following two values different, whereas DateTimeOffset
considers them equal:
July 01 2007 09:00:00 +00:00 (GMT)
July 01 2007 03:00:00 −06:00 (local time, Central America)

Convert from DateTime to DateTimeOffset

You can construct a DateTimeOffset from an existing DateTime either by using these
constructors:

public DateTimeOffset (DateTime dateTime);
public DateTimeOffset (DateTime dateTime, TimeSpan offset);

or with an implicit cast. The implicit cast from DateTime to DateTimeOffset is handy because most of the .NET Framework supports DateTime—not DateTimeOffset.

DateTimeOffset dt = new DateTime (2000, 2, 3);

If you don’t specify an offset, it’s inferred from the DateTime value using these rules:

  • If the DateTime has a DateTimeKind of Utc, the offset is zero.
  • If the DateTime has a DateTimeKind of Local or Unspecified (the default), the offset is taken from the current local time zone.

Convert from DateTimeOffset to DateTime

DateTimeOffset provides three properties that return values of type DateTime :

  1. The UtcDateTime property returns a DateTime in UTC time.
  2. The LocalDateTime property returns a DateTime in the current local time zone (converting it if necessary).
  3. The DateTime property returns a DateTime in whatever zone it was specified, with a Kind of Unspecified (i.e., it returns the UTC time plus the offset).

TimeZone and TimeZoneInfo

TimeZoneInfo was introduced in Framework 3.5. 
The biggest difference between the two types is that TimeZone lets you access only the current local time zone, whereas TimeZoneInfo provides access to all the world’s time zones. Further, TimeZoneInfo exposes a richer (although at times, more awkward) rules-based model for describing daylight saving time.


Tuples

Framework 4.0 introduced a new set of generic classes for holding a set of differently
typed elements. These are called tuples.

You can instantiate a tuple either via its constructor or via the static helper method Tuple.Create:

var t = new Tuple<int,string> (123, "Hello");
Tuple<int,string> t = Tuple.Create (123, "Hello");

You can then access the properties as follows (notice that each is statically typed):

Console.WriteLine (t.Item1 * 2);  // 246
Console.WriteLine (t.Item2.ToUpper());  // HELLO

Tuples are convenient in returning more than one value from a method—or creating
collections of value pairs (we’ll cover collections in the following chapter).

An alternative to tuples is to use an object array. However, you then lose static type
safety, incur the cost of boxing/unboxing for value types, and require clumsy casts
that cannot be validated by the compiler:

object[] items = { 123, "Hello" };
Console.WriteLine ( ((int) items[0]) * 2) ;
Console.WriteLine ( ((string) items[1]).ToUpper() );

Comparing Tuples:

var t1 = Tuple.Create (123, "Hello");
var t2 = Tuple.Create (123, "Hello");
Console.WriteLine (t1 == t2);  // False
Console.WriteLine (t1.Equals (t2));  // True

Guid

The static Guid.NewGuid method generates a unique Guid:

Guid g = Guid.NewGuid ();
Console.WriteLine (g.ToString());  // 0d57629c-7d6e-4847-97cb-9e2fc25083fe

To instantiate an existing value, you use one of the constructors. The two most useful constructors are:

public Guid (byte[] b);  // Accepts a 16-byte array
public Guid (string g);  // Accepts a formatted string

Being a struct, a Guid honors value-type semantics; hence, the equality operator works.
The static Guid.Empty property returns an empty Guid (all zeros). This is often used in place of null .


Equality Comparison

There are three standard protocols that types can implement for equality comparison:

  1. The == and != operators
  2. The virtual Equals method in object
  3. The IEquatable<T> interface



1.
Because object is a class (and so a reference type), object’s == operator uses referential equality to compare x and y. The result is false, because x and y each refer to different boxed objects on the heap. "==" and "!=" are operators, i.e. static and resolved at compiling time.

int x = 5, y = 5;

Console.WriteLine (x == y); // True

object x = 5, y = 5;
Console.WriteLine (x == y); // False


2.
Object.Equals method is resolved at runtime - according to the object's actual type. In this example below, it calls Int32’s Equals method, which applies value equality to the operands, returning true. With reference types, Equals performs referential equality comparison by default; with structs, Equals performs structural comparison by calling Equals on each of its fields.

object x = 5, y = 5;
Console.WriteLine (x.Equals (y)); // True

Occasionally, you need to force referential equality comparison. The static object.ReferenceEquals method


3.
Since the Equals method has a parameter of type Object, a cast will be needed in order to be able to access class specific members. Tus A consequence of calling object.Equals is that it forces boxing on value types. This is undesirable in highly performance-sensitive scenarios because boxing is relatively expensive compared to the actual comparison.

The idea is that IEquatable<T>, when implemented, gives the same result as calling object’s virtual Equals method—but more quickly. Most basic .NET types implement IEquatable<T>. You can use IEquatable<T> as a constraint in a generic type:

class Test<T> where T : IEquatable<T>
{
public bool IsEqual (T a, T b)
{
return a.Equals (b); // No boxing with generic T
}
}

If we remove the generic constraint, the class would still compile, but a.Equals(b) would instead bind to the slower object.Equals (slower assuming T was a value type).

Note. the runtime will use the IEquatable.Equals method only if you pass an object with the same type as defined in the interface implementation; otherwise, it will use the Object.Equals method.
Therefore, in order to align the same result of both interface and object equals() method, we need to do both work:  http://www.codeproject.com/Articles/20592/Implementing-IEquatable-Properly/

 
Order Comparison

The basic protocols for determining the order of objects:

  • The IComparable interfaces (IComparable and IComparable<T>)
  • The > and < operators

The IComparable interfaces are defined as follows:

  • public interface IComparable { int CompareTo (object other); }
  • public interface IComparable<in T> { int CompareTo (T other); }







































Wednesday, July 1, 2015

C# in Nutshell Chapter 4 Advanced C#

Delegates

A delegate is an object that knows how to call a method.

delegate int Transformer (int x);
class Test
{
static void Main()
{
Transformer t = Square;  // Create delegate instance
int result = t(3);    // Invoke delegate
Console.WriteLine (result);  // 9
}
static int Square (int x) { return x * x; }
}

plug-in methods with Delegates 

public delegate int Transformer (int x);
class Util
{
public static void Transform (int[] values, Transformer t)
{
for (int i = 0; i < values.Length; i++)
values[i] = t (values[i]);
}
}
class Test
{
static void Main()
{
int[] values = { 1, 2, 3 };
Util.Transform (values, Square);  // Hook in the Square method
foreach (int i in values)
Console.Write (i + " ");   // 1 4 9
}

static int Square (int x) { return x * x; }
}

Multicast Delegates

All delegate instances have multicast capability. This means that a delegate instance
can reference not just a single target method, but also a list of target methods. The
+ and += operators combine delegate instances. For example:

SomeDelegate d = SomeMethod1;
d += SomeMethod2;

Note. Delegates are immutable, so when you call += or −=, you’re in fact creating a new delegate instance and assigning it to the existing variable.

If a multicast delegate has a nonvoid return type, the caller receives the return value from the last method to be invoked. The preceding methods are still called, but their return values are discarded.

Multicast example:

class Test
{
static void Main()
{
ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile;
Util.HardWork (p);
}
static void WriteProgressToConsole (int percentComplete)
{
Console.WriteLine (percentComplete);
}
static void WriteProgressToFile (int percentComplete)
{
System.IO.File.WriteAllText ("progress.txt",
percentComplete.ToString());
}
}


Delegate v.s Interface

A problem that can be solved with a delegate can also be solved with an interface.

A delegate design may be a better choice than an interface design if one or more of
these conditions are true:
• The interface defines only a single method.
• Multicast capability is needed.
• The subscriber needs to implement the interface multiple times.


Delegate Parameter compatibility

When you call a method, you can supply arguments that have more specific types
than the parameters of that method. This is ordinary polymorphic behavior. For
exactly the same reason, a delegate can have more specific parameter types than its
method target. This is called contravariance.

Delegate Return type compatibility

If you call a method, you may get back a type that is more specific than what you
asked for. This is ordinary polymorphic behavior. For exactly the same reason, a
delegate target method may return a more specific type than described by the delegate.
This is called covariance.

Events in Delegates

The main purpose of events is to prevent subscribers from interfering with each other.
For example below, if we remove the event keyword from our example so that PriceChanged becomes an ordinary delegate field, our example would give the same results. However, Stock
would be less robust, in that subscribers could do the following things to interfere
with each other:
  1. Replace other subscribers by reassigning PriceChanged (instead of using the += operator).
  2. Clear all subscribers (by setting PriceChanged to null).
  3. Broadcast to other subscribers by invoking the delegate.
Code within the Stock type has full access to PriceChanged and can treat it as a delegate. Code outside of Stock can only perform += and −= operations on the PriceChanged event.


public delegate void PriceChangedHandler (decimal oldPrice, decimal newPrice);

public class Stock
{
string symbol;
decimal price;
public Stock (string symbol) { this.symbol = symbol; }
public event PriceChangedHandler PriceChanged;
public decimal Price
{
get { return price; }
set
{
if (price == value) return; // Exit if nothing has changed
decimal oldPrice = price;
price = value;
if (PriceChanged != null) // If invocation list not
PriceChanged (oldPrice, price); // empty, fire event.
}
}
}

throw v.s. throw ex

try { ... }
catch (Exception ex)
{
// Log error
...
throw; // Rethrow same exception
}

If we replaced throw with throw ex, the example would still work, but the StackTrace property of the newly propagated exception would no longer reflect the original error.


Preprocessor Directives



































Tuesday, June 30, 2015

C# Nutshell Chapter 3 Creating Types in C#

Object Initializers

To simplify object initialization, any accessible fields or properties of an object can
be set via an object initializer directly after construction.

public class Bunny
{
public string Name;
public bool LikesCarrots;
public bool LikesHumans;
public Bunny () {}
public Bunny (string n) { Name = n; }
}

// Note parameterless constructors can omit empty parentheses
Bunny b1 = new Bunny { Name="Bo", LikesCarrots=true, LikesHumans=false };
Bunny b2 = new Bunny ("Bo") { LikesCarrots=true, LikesHumans=false };

Properties

Properties look like fields from the outside, but internally they contain logic, like
methods do.
A property is declared like a field, but with a get/set block added. Here’s how to
implement CurrentPrice as a property:
public class Stock
{
decimal currentPrice; // The private "backing" field
public decimal CurrentPrice // The public property
{
get { return currentPrice; } set { currentPrice = value; }
}
}

Const v.s. static readonly

A static readonly field is also advantageous when exposing to
other assemblies a value that might change in a later version.
For instance, suppose assembly X exposes a constant as follows:
public const decimal ProgramVersion = 2.3;
If assembly Y references X and uses this constant, the value 2.3
will be baked into assembly Y when compiled. This means that
if X is later recompiled with the constant set to 2.4, Y will still
use the old value of 2.3 until Y is recompiled. A static
readonly field avoids this problem.
Another way of looking at this is that any value that might
change in the future is not constant by definition, and so should
not be represented as one.


Structs

A struct is similar to a class, with the following key differences:
  • • A struct is a value type, whereas a class is a reference type.
  • • A struct does not support inheritance (other than implicitly deriving from object, or more precisely, System.ValueType).

A struct can have all the members a class can, except the following:
  • • A parameterless constructor
  • • A finalizer
  • • Virtual members
public struct Point
{
int x = 1; // Illegal: cannot initialize field
int y;
public Point() {} // Illegal: cannot have
// parameterless constructor
public Point (int x) {this.x = x;} // Illegal: must assign field y
}

Class Access Modifiers

public
Fully accessible. This is the implicit accessibility for members of an enum or
interface.
internal
Accessible only within containing assembly or friend assemblies. This is the
default accessibility for non-nested types.
private
Accessible only within containing type. This is the default accessibility for
members of a class or struct.
protected
Accessible only within containing type or subclasses.

Class2 is accessible from outside its assembly; Class1 is not:

class Class1 {} // Class1 is internal (default)
public class Class2 {}

ClassB exposes field x to other types in the same assembly; ClassA does not:

class ClassA { int x; } // x is private (default)
class ClassB { internal int x; }

Functions within Subclass can call Bar but not Foo:

class BaseClass
{
void Foo() {} // Foo is private (default)
protected void Bar() {}
}
class Subclass : BaseClass
{
void Test1() { Foo(); } // Error - cannot access Foo
void Test2() { Bar(); } // OK
}

Constructors and Inheritance

A subclass must declare its own constructors. The base class’s constructors are
accessible to the derived class, but are never automatically inherited.

public class Baseclass
{
public int X;
public Baseclass () { }
public Baseclass (int x) { this.X = x; }
}
public class Subclass : Baseclass { }
//the following is illegal:
Subclass s = new Subclass (123);

Subclass must hence “redefine” any constructors it wants to expose. In doing so,
however, it can call any of the base class’s constructors with the base keyword:
public class Subclass : Baseclass
{
public Subclass (int x) : base (x) { }
}

If a constructor in a subclass omits the base keyword, the base type’s parameterless constructor is implicitly called. If the base class has no accessible parameterless constructor, subclasses are forced to use the base keyword in their constructors.

public class BaseClass
{
public int X;
public BaseClass() { X = 1; }  //without this, subclass has to use 'base' keyword
}
public class Subclass : BaseClass
{
public Subclass() { Console.WriteLine (X); } // 1
}


Using Interface or Superclass

As a guideline:
• Use classes and subclasses for types that naturally share an implementation.
• Use interfaces for types that have independent implementations.
Consider the following classes:
abstract class Animal {}
abstract class Bird : Animal {}
abstract class Insect : Animal {}
abstract class FlyingCreature : Animal {}
abstract class Carnivore : Animal {}
// Concrete classes:
class Ostrich : Bird {}
class Eagle : Bird, FlyingCreature, Carnivore {} // Illegal
class Bee : Insect, FlyingCreature {} // Illegal
class Flea : Insect, Carnivore {} // Illegal

The Eagle, Bee, and Flea classes do not compile because inheriting from multiple
classes is prohibited. To resolve this, we must convert some of the types to interfaces.
The question then arises, which types? Following our general rule, we could
say that
insects share an implementation, and birds share an implementation, so
they remain classes. In contrast, flying creatures have independent mechanisms
for flying, and carnivores have independent strategies for eating animals, 
so we
would convert FlyingCreature and Carnivore to interfaces:
interface IFlyingCreature {}
interface ICarnivore {}


Enum initialization

It is different from other type initialization. 

public enum BorderSide { Left, Right, Top, Bottom }
BorderSide topSide = BorderSide.Top;
bool isTop = (topSide == BorderSide.Top); // true


Enum Operator Type-safety Issues

Since an enum can be cast to and from its underlying integral type, the actual value
it may have may fall outside the bounds of a legal enum member

BorderSide b = BorderSide.Bottom;
b++; // No errors

An invalid BorderSide would break the following code:

void Draw (BorderSide side)
{
if (side == BorderSide.Left) {...}
else if (side == BorderSide.Right) {...}
else if (side == BorderSide.Top) {...}
else {...} // Assume BorderSide.Bottom
}

One solution is to add another else clause:
...
else if (side == BorderSide.Bottom) ...
else throw new ArgumentException ("Invalid BorderSide: " + side, "side");

Another workaround is to explicitly check an enum value for validity. The static
Enum.IsDefined method does this job:

BorderSide side = (BorderSide) 12345;
Console.WriteLine (Enum.IsDefined (typeof (BorderSide), side)); // False































Monday, June 29, 2015

C# Nutshell Chapter 1-2 Basics

"==" makes a compile-time decision

int x = 1;
int y = 1;
x == y // true

object x = 1;
object y = 1;
x == y // false; referential equality from object's == operator

"Equals" is resolved at runtime, according to the object's actual type

object x = 1;
object y = 1;
x.Equals(y);  //true


object class static helper method providing null-safe equality comparision

object x = 3, y = 3;
Console.WriteLine (object.Equals (x, y)); // True
x = null;
Console.WriteLine (object.Equals (x, y)); // False
y = null;
Console.WriteLine (object.Equals (x, y)); // True

implicitly assigned default value

static void Main()
{
int x;
Console.WriteLine (x); // Compile-time error
}


class Test
{
static int x;
static void Main() { Console.WriteLine (x); } // 0
}

"ref" and "out" keywords


  • "ref" - pass in as reference rather than value
  • "out" - no need to be assigned before going into the function, but must be assigned before comes out of the function. 
  • both "ef"and "out" are passed in by reference

"params" modifier

The params parameter modifier may be specified on the last parameter of a method
so that the method accepts any number of parameters of a particular type.

static int Sum (int a, int b, params int[] ints)
{
Console.WriteLine(a);
Console.WriteLine(b);
int sum = 0;
for (int i = 0; i < ints.Length; i++)
sum += ints[i]; // Increase sum by ints[i]
return sum;
}

Optional parameters

void Foo (int x = 23) { Console.WriteLine (x); }
Foo(); // 23

Mandatory parameters must occur before optional parameters in both the method declaration and the method call public method that’s called from another assembly requires recompilation of both assemblies.

void Foo (int x = 0, int y = 0) { Console.WriteLine (x + ", " + y); }
void Test()
{
Foo(1); // 1, 0
}

Named arguments

Rather than identifying an argument by position, you can identify an argument by
name.

void Foo (int x, int y) { Console.WriteLine (x + ", " + y); }
void Test()
{
Foo (y:2, x:1); // 1, 2
}

Named arguments are particularly useful in conjunction with optional parameters.
For instance, consider the following method:
void Bar (int a = 0, int b = 0, int c = 0, int d = 0) { ... }
We can call this supplying only a value for d as follows:
Bar (d:3);