使用delegates委托寫插件方法:
public delegate int Transformer (int x); public 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 = new int[] {1, 2, 3}; Util.Transform(values, Square); // dynamically hook in Square foreach (int i in values) Console.Write (i + " "); // 1 4 9 } static int Square (int x) { return x * x; } }
多重delegate委托例子:
public delegate void ProgressReporter (int percentComplete); public class Util { public static void HardWork (ProgressReporter p) { for (int i = 0; i < 10; i++) { p (i * 10); // Invoke delegate System.Threading.Thread.Sleep(100); // Simulate hard work } } }
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()); } }
實例方法目標:
public delegate void ProgressReporter (int percentComplete); class Test { static void Main() {new Test();} Test () { ProgressReporter p = InstanceProgress; p(99); // 99 Console.WriteLine (p.Target == this); // True Console.WriteLine (p.Method); // Void InstanceProgress(Int32) } void InstanceProgress (int percentComplete) { Console.WriteLine(percentComplete); } }
泛Delegate委托類型:
public delegate T Transformer<T> (T arg); public class Util { public static void Transform<T> (T[] values, Transformer<T> t) { for (int i = 0; i < values.Length; i++) values[i] = t(values[i]); } } class Test { static void Main() { int[] values = new int[] {1, 2, 3}; Util.Transform(values, Square); // dynamically hook in Square foreach (int i in values) Console.Write (i + " "); // 1 4 9 } static int Square (int x) { return x * x; } }
Delegates委托和Interfaces接口:
public interface ITransformer { int Transform (int x); } public class Util { public static void TransformAll (int[] values, ITransformer t) { for (int i = 0; i < values.Length; i++) values[i] = t.Transform(values[i]); } } class Test : ITransformer { static void Main() { int[] values = new int[] {1, 2, 3}; Util.TransformAll(values, new Test()); foreach (int i in values) Console.WriteLine (i); } public int Transform (int x) { return x * x; } }
class Test { static void Main() { int[] values = new int[] {1, 2, 3}; Util.TransformAll(values, new Cuber()); foreach (int i in values) Console.WriteLine (i); } class Squarer : ITransformer { public int Transform (int x) { return x * x; } } class Cuber : ITransformer { public int Transform (int x) {return x * x * x; } } }
Delegate委托參數兼容 (逆變):
delegate void SpecificDelegate (SpecificClass s); class SpecificClass {} class Test { static void Main() { SpecificDelegate specificDelegate = GeneralHandler; specificDelegate (new SpecificClass()); } static void GeneralHandler(object o) { Console.WriteLine(o.GetType()); // SpecificClass } }
Delegate委托返回類型兼容 (逆變):
delegate Asset DebtCollector(); class Asset {} class House : Asset {} class Test { static void Main() { DebtCollector d = new DebtCollector (GetHomeSweetHome); Asset a = d(); Console.WriteLine(a.GetType()); // House } static House GetHomeSweetHome() {return new House(); } }
Events事件:
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 if (PriceChanged != null) // if invocation list not empty PriceChanged (price, value); // fire event price = value; } } }
標准Event事件模式:
using System; public class PriceChangedEventArgs : EventArgs { public readonly decimal LastPrice; public readonly decimal NewPrice; public PriceChangedEventArgs (decimal lastPrice, decimal newPrice) { LastPrice = lastPrice; NewPrice = newPrice; } } public class Stock { string symbol; decimal price; public Stock (string symbol) {this.symbol = symbol;} public event EventHandler<PriceChangedEventArgs> PriceChanged; protected virtual void OnPriceChanged (PriceChangedEventArgs e) { if (PriceChanged != null) PriceChanged (this, e); } public decimal Price { get { return price; } set { if (price == value) return; OnPriceChanged (new PriceChangedEventArgs (price, value)); price = value; } } } class Test { static void Main() { Stock stock = new Stock ("THPW"); stock.Price = 27.10M; // register with the PriceChanged event stock.PriceChanged += stock_PriceChanged; stock.Price = 31.59M; } static void stock_PriceChanged (object sender, PriceChangedEventArgs e) { if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M) Console.WriteLine ("Alert, 10% stock price increase!"); } }
使用EventArgs.Empty:
public class Stock { string symbol; decimal price; public Stock (string symbol) {this.symbol = symbol;} public event EventHandler PriceChanged; protected virtual void OnPriceChanged (EventArgs e) { if (PriceChanged != null) PriceChanged (this, e); } public decimal Price { get { return price; } set { if (price == value) return; price = value; OnPriceChanged (EventArgs.Empty); } } }
Event存取:
public interface IFoo { event EventHandler Ev; } class Foo : IFoo { private EventHandler ev; event EventHandler IFoo.Ev { add { ev += value; } remove { ev -= value; } } }
Lambda表達式:
delegate int Transformer (int i); class Test { static void Main() { Transformer square = x => x * x; Console.WriteLine (square(3)); // 9 } }
捕獲外部變量(閉包):
delegate int NumericSequence (); class Test { static void Main() { int seed = 0; NumericSequence natural = () => seed++; Console.WriteLine (natural()); // 0 Console.WriteLine (natural()); // 1 } }
delegate int NumericSequence (); class Test { static NumericSequence Natural () { int seed = 0; // executes once (per call to Natural()) return () => seed++; // executes twice (per call to delegate instance // returned by Natural()) } static void Main() { NumericSequence natural = Natural (); Console.WriteLine (natural()); // 0 Console.WriteLine (natural()); // 1 } }
delegate int NumericSequence (); class Test { static NumericSequence Natural () { return () => {int seed = 0; return seed++; }; } static void Main() { NumericSequence natural = Natural (); Console.WriteLine (natural()); // 0 Console.WriteLine (natural()); // 0 } }
匿名方法:
delegate int Transformer (int i); class Test { static void Main() { Transformer square = delegate (int x) {return x * x;}; Console.WriteLine (square(3)); // 9 } }
Try語句和異常:
class Test { static int Calc (int x) {return 10 / x;} static void Main() { try { int y = Calc (0); Console.WriteLine (y); } catch (DivideByZeroException ex) { Console.WriteLine("x cannot be zero"); } Console.WriteLine ("program completed"); } }
多Catch語句:
class Test { static void Main (string[] args) { try { byte b = byte.Parse (args[0]); Console.WriteLine (b); } catch (IndexOutOfRangeException ex) { Console.WriteLine ("Please provide at least one argument"); } catch (FormatException ex) { Console.WriteLine ("That's not a number!"); } catch (OverflowException ex) { Console.WriteLine ("You've given me more than a byte!"); } } }
Finally語句塊:
using System; using System.IO; class Test { static void Main () { StreamReader reader = null; try { reader = File.OpenText ("file.txt"); if (reader.EndOfStream) return; Console.WriteLine (reader.ReadToEnd ()); } finally { if (reader != null) reader.Dispose (); } }
使用語句:
StreamReader reader = File.OpenText ("file.txt"); try { // ... } finally { if (reader != null) ((IDisposable)reader).Dispose(); }
拋出異常:
class Test { static void Display (string name) { if (name == null) throw new ArgumentNullException ("name"); Console.WriteLine (name); } static void Main() { try { Display (null); } catch (ArgumentNullException ex) { Console.WriteLine ("Caught the exception"); } } }
重新拋出:
string s; using (WebClient wc = new WebClient()) try { s = wc.DownloadString ("http://albahari.com/"); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.NameResolutionFailure) Console.WriteLine ("Bad domain name"); else throw; // Can't handle other sorts of WebException, so rethrow }
原子模式:
class Test { static void Main() { Accumulator a = new Accumulator (); try { a.Add (4, 5); // a.Total is now 9 a.Add (1, int.MaxValue); // will cause OverflowException } catch (OverflowException) { Console.WriteLine (a.Total); // a.Total is still 9 } } }
public class Accumulator { public int Total; public void Add(params int[] ints) { bool success = false; int totalSnapshot = Total; try { foreach (int i in ints) { checked { Total += i; } } success = true; } finally { if (! success) Total = totalSnapshot; } } }
迭代器:
using System; using System.Collections.Generic; class Test { static void Main() { foreach (int fib in Fibs(6)) Console.Write (fib + " "); } static IEnumerable<int> Fibs(int fibCount) { for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++) { yield return prevFib; int newFib = prevFib+curFib; prevFib = curFib; curFib = newFib; } } }
多yield語句:
class Test { static void Main() { foreach (string s in Foo()) Console.WriteLine(s); // prints "One","Two","Three" } static IEnumerable<string> Foo() { yield return "One"; yield return "Two"; yield return "Three"; } }
Yield break:
static IEnumerable<string> Foo(bool breakEarly) { yield return "One"; yield return "Two"; if (breakEarly) yield break; yield return "Three"; }
構成序列:
using System; using System.Collections.Generic; class Test { static void Main() { foreach (int fib in EvenNumbersOnly(Fibs(6))) Console.WriteLine(fib); } static IEnumerable<int> Fibs(int fibCount) { for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++) { yield return prevFib; int newFib = prevFib+curFib; prevFib = curFib; curFib = newFib; } } static IEnumerable<int> EvenNumbersOnly(IEnumerable<int> sequence) { foreach(int x in sequence) if ((x % 2) == 0) yield return x; } }
Nullable 類型: 操作升降:
int? x = 5; int? y = null; // equality operator examples Console.WriteLine(x == y); // false Console.WriteLine(x == null); // false Console.WriteLine(x == 5); // true Console.WriteLine(y == null); // true Console.WriteLine(y == 5); // false Console.WriteLine(y != 5); // true // relational operator examples Console.WriteLine(x < 6); // true Console.WriteLine(y < 6); // false Console.WriteLine(y > 6); // false // all other operator examples Console.WriteLine(x + 5); // 10 Console.WriteLine(x + y); // null (prints empty line)
bool? 語義:
bool? n = null; bool? f = false; bool? t = true; Console.WriteLine (n | n); // (null) Console.WriteLine (n | f); // (null) Console.WriteLine (n | t); // True Console.WriteLine (n & n); // (null) Console.WriteLine (n & f); // False Console.WriteLine (n & t); // (null)
環境屬性:
public class Row { // ... Grid parent; Color? backColor; public Color BackColor { get { return backColor ?? parent.BackColor; } set { backColor = backColor == parent.BackColor ? null : value; } } }
操作符重載:
public struct Note { int value; public Note (int semitonesFromA) { value = semitonesFromA; } public static Note operator + (Note x, int semitones) { return new Note (x.value + semitones); } }
自定義轉換:
// Convert to hertz public static implicit operator double(Note x) { return 440 * Math.Pow (2,(double) x.value / 12 ); } // Convert from hertz (only accurate to nearest semitone) public static explicit operator Note(double x) { return new Note ((int) (0.5 + 12 * (Math.Log(x/440) / Math.Log(2)) )); }
重載true和false:
class Test { static void Main() { SqlBoolean a = SqlBoolean.Null; if (a) Console.WriteLine("True"); else if (! a) Console.WriteLine("False"); else Console.WriteLine("Null"); } }
public struct SqlBoolean { public static bool operator true (SqlBoolean x) { return x.m_value == True.m_value; } public static bool operator false (SqlBoolean x) { return x.m_value == False.m_value; } public static SqlBoolean operator !(SqlBoolean x) { if (x.m_value == Null.m_value) return Null; if (x.m_value == False.m_value) return True; return False; } public static readonly SqlBoolean Null = new SqlBoolean(0); public static readonly SqlBoolean False = new SqlBoolean(1); public static readonly SqlBoolean True = new SqlBoolean(2); private SqlBoolean (byte value) {m_value = value;} private byte m_value; }
擴展方法:
public static class StringHelper { public static bool IsCapitalized (this string s) { if (string.IsNullOrEmpty(s)) return false; return char.IsUpper(s[0]); } }
在接口上擴展方法:
using System; using System.Collections.Generic; static class Test { static void Main() { var strings = new string[] { "a", "b", null, "c"}; foreach (string s in strings.StripNulls()) Console.WriteLine(s); } static IEnumerable<T> StripNulls<T> (this IEnumerable<T> seq) { foreach (T t in seq) if (t != null) yield return t; } }
不安全代碼:
unsafe void RedFilter(int[,] bitmap) { int length = bitmap.Length; fixed (int* b = bitmap) { int* p = b; for(int i = 0; i < length; i++) *p++ &= 0xFF; } }
fixed語句:
class Test { int x; static void Main() { Test test = new Test (); unsafe { fixed(int* p = &test.x) // pins test { *p = 9; } System.Console.WriteLine(test.x); } } }
成員指向操作符:
struct Test { int x; unsafe static void Main() { Test test = new Test(); Test* p = &test; p->x = 9; System.Console.WriteLine(test.x); } }
stackalloc:
int* a = stackalloc int [10]; for (int i = 0; i < 10; ++i) Console.WriteLine(a[i]); // print raw memory
Fixed-size buffers:
unsafe struct UnsafeUnicodeString { public short Length; public fixed byte Buffer[30]; } unsafe class UnsafeClass { private UnsafeUnicodeString uus; public UnsafeClass (string s) { uus.Length = (short)s.Length; fixed (byte* p = uus.Buffer) for (int i = 0; i < s.Length; i++) p[i] = (byte)s[i]; } } class Test {
void*:
class Test { unsafe static void Main () { short[ ] a = {1,1,2,3,5,8,13,21,34,55}; fixed (short* p = a) { //sizeof returns size of value-type in bytes Zap (p, a.Length * sizeof (short)); } foreach (short x in a) System.Console.WriteLine (x); // prints all zeros } unsafe static void Zap (void* memory, int byteCount) { byte* b = (byte*)memory; for (int i = 0; i < byteCount; i++) *b++ = 0; } }
預處理器指令:
#define DEBUG class MyClass { int x; void Foo() { # if DEBUG Console.WriteLine("Testing: x = {0}", x); # endif } ... }
條件屬性:
// file1.cs #define DEBUG using System; using System.Diagnostics; [Conditional("DEBUG")] public class TestAttribute : Attribute {} // file2.cs #define DEBUG [Test] class Foo { [Test] private string s; }
#pragma warning:
public class Foo { static void Main() { } #pragma warning disable 414 static string Message = "Hello"; #pragma warning restore 414 }
XML文檔:
using System; class Test { /// <summary> /// The Foo method is called from /// <see cref="Main">Main</see> /// </summary> /// <mytag>user defined tag info</mytag> /// <param name="s">Description for s</param> static void Foo(string s) { Console.WriteLine(s); } static void Main() { Foo("42"); } }
namespace NS { /// T:NS.MyClass class MyClass { /// F:NS.MyClass.aField string aField; /// P:NS.MyClass.aProperty short aProperty {get {...} set {...}} /// T:NS.MyClass.NestedType class NestedType {...}; /// M:NS.MyClass.X() void X() {...} /// M:NS.MyClass.Y(System.Int32,System.Double@,System.Decimal@) void Y(int p1, ref double p2, out decimal p3) {...} /// M:NS.MyClass.Z(System.Char[ ],System.Single[0:,0:]) void Z(char[ ] 1, float[,] p2) {...} /// M:NS.MyClass.op_Addition(NS.MyClass,NS.MyClass) public static MyClass operator+(MyClass c1, MyClass c2) {...} /// M:NS.MyClass.op_Implicit(NS.MyClass)~System.Int32 public static implicit operator int(MyClass c) {...} /// M:NS.MyClass.#ctor MyClass() {...} /// M:NS.MyClass.Finalize ~MyClass() {...} /// M:NS.MyClass.#cctor static MyClass() {...} } }