使用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; }
}
}
caozuofu.html" target="_blank">操作符重载:
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() {...}
}
}