1. System.Environment and System.Console
1: public class Program
2: {
3: private static void Main()
4: {
5: Console.ForegroundColor = ConsoleColor.DarkGreen;
6:
7: string[] aArgs = Environment.GetCommandLineArgs();
8: foreach (string aArg in aArgs)
9: {
10: Console.WriteLine("Command Line Args : {0}", aArg);
11: }
12:
13: Console.WriteLine("Current OS: {0}", Environment.OSVersion);
14:
15: Console.WriteLine("Current Directory: {0}", Environment.CurrentDirectory);
16:
17: string[] aDrives = Environment.GetLogicalDrives();
18: foreach (string aDrive in aDrives)
19: {
20: Console.WriteLine("Drive {0}", aDrive);
21: }
22:
23: Console.WriteLine("Executing version of .NET: {0} ", Environment.Version);
24: }
25: }
2. String Formatting Flags
3. Type Visibility
Types (classes, interfaces, structures, enumerations, and delegates) can also take accessibility modifiers,
but are limited to public or internal. (Nested type can be private).
4. Const Fields VS Read-Only Fields VS Static Read-Only Fields
Const Fields:
It is important to understand that the value assigned to a constant variable must be known at compile
time, and therefore a constant member cannot be assigned to an object reference (whose value is
computed at runtime)
1: internal class ConstData
2: {
3: // The value assigned to a const must be known at compile time.
4: public const string BEST_NBA_TEAM = "Timberwolves";
5: public const double SIMPLE_PI = 3.14;
6: public const bool TRUTH = true;
7: public const bool FALSITY = !TRUTH;
8: }
1: .field public static literal string BEST_NBA_TEAM = string('Timberwolves')
You can see the value is hard-coded directly into the assembly! And constant fields are implicitly static!
Read-Only Fields
As mentioned earlier, the value assigned to a constant must be known at compile time. However, what
if you wish to create an unchangeable field whose initial value is not known until runtime? Then read-only fields in the choice.
Unlike const however, read-only fields are not implicitly static; therefore if you wish to expose such data at class level, the static keyword must be included.
1: class Tire
2: {
3: public readonly static Tire GoodStone = new Tire(90);
4: public readonly static Tire FireYear = new Tire(100);
5: public int manufactureID;
6: public Tire() {}
7: public Tire(int ID)
8: { manufactureID = ID; }
9: }
Read-only fields have another distinction from constant data: their value may be assigned within the scope of a constructor. This can be very useful if the value to assign to a read-only field must be read from an external source (such as a text file or database).
Static Read-Only Fields
Unlike constant data, read-only fields are not implicitly static. If you wish to allow object users to obtain the value of a read-only field from the class level, simply make use of the static keyword:
5. Static Constructor
Static constructor is mainly used to initialize the static field.
虽然static field的值可以在声明的时候进行赋值,但是有时候可能该值不是简单的字面值或者一个expression就可以搞定,像new XXX()之类,如果需要进行好几个statement操作才可以得到该static field的初始值(比如说从数据库中取值),这个时候需要把这些操作放到一个方法里面才行。如果是放到instance constructor里面,这样每实例化一个对象的时候,这个static field就会被重新赋值一下,就失去了static field的真正意义,因此这个时候需要把这些操作放到static constructor中。
Here are a few points of interest regarding static constructors:
• A given class (or structure) may define only a single static constructor.
• A static constructor executes exactly one time, regardless of how many objects of the type are created.
• 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.
6. Static Classes
C# 2005 (c# 2.0) has widened the scope of the static keyword by introducing static classes.When a class has been defined as static, it is not creatable using the new keyword, and it can contain only static members or fields (if this is not the case, you receive compiler errors).
At first glance, this might seem like a very useless feature, given that a class that cannot be created does not appear all that helpful. However, if you create a class that contains nothing but static members and/or constant data, the class has no need to be allocated in the first place.
Prior to C# 2005, the only way to prevent an object user from creating such a type was to either redefine the default constructor as private or mark the class as an abstract type using the C# abstract keyword.
7. The Switch Statement
One nice feature of the C# switch statement is that you can evaluate string data in addition to numeric data.
8. System.Object
1: // The topmost class in the .NET universe: System.Object
2: namespace System
3: {
4: public class Object
5: {
6: public Object();
7: public virtual Boolean Equals(Object obj);
8: public virtual Int32 GetHashCode();
9: public Type GetType();
10: public virtual String ToString();
11: protected virtual void Finalize();
12: protected Object MemberwiseClone();
13: public static bool Equals(object objA, object objB);
14: public static bool ReferenceEquals(object objA, object objB);
15: }
16: }
static : Equals / ReferenceEquals
virtual: Equals (reference comparison by default)/ GetHashCode
protected: MemberwiseClone / Finalize
Override GetHashCode()
By and large, overriding this method is only useful if you intend to store a custom type within
a hash-based collection such as System.Collections.Hashtable. Under the hood, the Hashtable type
calls the Equals() and GetHashCode() members of the contained types to determine the correct object
to return to the caller.
There are many algorithms that can be used to create a hash code—some fancy, others not so fancy. As mentioned, an object’s hash value will be based on its state data. As luck would have it, the System.String class has a very solid implementation of GetHashCode() that is based on the string’s
character data.
9. System.String
You should be aware that although string is a reference type, the equality operators (== and !=) are defined to compare the value with the string objects, not the memory to which they refer.
10. Nullable Type
1: [Serializable, StructLayout(LayoutKind.Sequential), TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")]
2: public struct Nullable<T> where T: struct
3: {
4: private bool hasValue;
5: internal T value;
6: public Nullable(T value);
7: public bool HasValue { get; }
8: public T Value { get; }
9: public T GetValueOrDefault();
10: public T GetValueOrDefault(T defaultValue);
11: public override bool Equals(object other);
12: public override int GetHashCode();
13: public override string ToString();
14: public static implicit operator T?(T value);
15: public static explicit operator T(T? value);
16: }
1: [Serializable, StructLayout(LayoutKind.Sequential), TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")]
2: public struct Nullable<T> where T: struct
3: {
4: private bool hasValue;
5: internal T value;
6: public Nullable(T value)
7: {
8: this.value = value;
9: this.hasValue = true;
10: }
11:
12: public bool HasValue
13: {
14: get
15: {
16: return this.hasValue;
17: }
18: }
19: public T Value
20: {
21: get
22: {
23: if (!this.HasValue)
24: {
25: ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
26: }
27: return this.value;
28: }
29: }
30: public T GetValueOrDefault()
31: {
32: return this.value;
33: }
34:
35: public T GetValueOrDefault(T defaultValue)
36: {
37: if (!this.HasValue)
38: {
39: return defaultValue;
40: }
41: return this.value;
42: }
43:
44: public override bool Equals(object other)
45: {
46: if (!this.HasValue)
47: {
48: return (other == null);
49: }
50: if (other == null)
51: {
52: return false;
53: }
54: return this.value.Equals(other);
55: }
56:
57: public override int GetHashCode()
58: {
59: if (!this.HasValue)
60: {
61: return 0;
62: }
63: return this.value.GetHashCode();
64: }
65:
66: public override string ToString()
67: {
68: if (!this.HasValue)
69: {
70: return "";
71: }
72: return this.value.ToString();
73: }
74:
75: public static implicit operator T?(T value)
76: {
77: return new T?(value);
78: }
79:
80: public static explicit operator T(T? value)
81: {
82: return value.Value;
83: }
84: }
85: