c#中的委托就是安全的指针,它可以帮我们回调函数。 下面看一下如何定义委托:
internal delegate void Feedback(Int32 value);
//我写一句话,其实编译器却把它编译成一个类
internal class Feedback : System.MulticastDelegate

...{
public Feedback(Object object, IntPtr method);
public virtual void Invoke(Int32 value);
public virtual IAsyncResult BeginInvoke(Int32 value,AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}
下面在看一下IL代码我们可以更清楚的认识它:

我们知道当我们使用Delegate类的Combine方法时,会把多个委托串成一个链,这里要注意的是如果回调的方法有返回值,那么只会返回最后那个回调方法的值。还有就是如果链上有一个方法抛出异常,那么将不再执行链上的其它方法。下面看一下c#为委托提供的便利语法:
//1.不需要定义委托对象

internal sealed class AClass ...{

public static void CallbackWithoutNewingADelegateObject() ...{
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 5); //这里不用写new WaitCallBack(SomeAsyncTask)
}

private static void SomeAsyncTask(Object o) ...{
Console.WriteLine(o);
}
}

//2.不需要定义回调方法(即匿名委托,c#3.0中的Lambda表达式)

internal sealed class AClass ...{

public static void CallbackWithoutNewingADelegateObject() ...{
ThreadPool.QueueUserWorkItem(

delegate(Object obj) ...{ Console.WriteLine(obj); },
5);
}
}

//3.不需要指定回调方法参数
button1.Click +=

delegate ...{ MessageBox.Show("The Button was clicked!"); };


还有c#为我们提供的+=,-=操作符去操作委托就不说了。
下面给出一个自定义属性的应用,由于本人对反射不是很了解,而自定义属性的用处就是在反射里面,所以就不详细说了:
using System;
using System.Diagnostics;
using System.Reflection;

[assembly: CLSCompliant(true)]
[Serializable]
[DefaultMemberAttribute("Main")]
[DebuggerDisplayAttribute("Richter", Name = "Jeff", Target = typeof(Program))]

public sealed class Program ...{
[Conditional("Debug")]
[Conditional("Release")]


public void DoSomething() ...{ }


public Program() ...{}

[CLSCompliant(true)]
[STAThread]

public static void Main() ...{
ShowAttributes(typeof(Program));
MemberInfo[] members = typeof (Program).FindMembers(MemberTypes.Constructor | MemberTypes.Method,BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public | BindingFlags.Static,Type.FilterName, "*");

foreach (MemberInfo member in members) ...{
ShowAttributes(member);
}
}


private static void ShowAttributes(MemberInfo attributeTarget) ...{
Attribute[] attributes = Attribute.GetCustomAttributes(attributeTarget);
Console.WriteLine("Attributes applied to {0}: {1}",attributeTarget.Name, (attributes.Length == 0 ? "None" : String.Empty));


foreach (Attribute attribute in attributes) ...{
Console.WriteLine(" {0}", attribute.GetType().ToString());

if (attribute is DefaultMemberAttribute)
Console.WriteLine(" MemberName={0}",((DefaultMemberAttribute) attribute).MemberName);

if (attribute is ConditionalAttribute)
Console.WriteLine(" ConditionString={0}",((ConditionalAttribute) attribute).ConditionString);

if (attribute is CLSCompliantAttribute)
Console.WriteLine(" IsCompliant={0}",((CLSCompliantAttribute) attribute).IsCompliant);

DebuggerDisplayAttribute dda = attribute as DebuggerDisplayAttribute;

if (dda != null) ...{
Console.WriteLine(" Value={0}, Name={1}, Target={2}",dda.Value, dda.Name, dda.Target);
}
}
Console.WriteLine();
}
}
//输出
Attributes applied to Program:
System.SerializableAttribute
System.Diagnostics.DebuggerDisplayAttribute
Value=Richter, Name=Jeff, Target=Program
System.Reflection.DefaultMemberAttribute
MemberName=Main

Attributes applied to DoSomething:
System.Diagnostics.ConditionalAttribute
ConditionString=Release
System.Diagnostics.ConditionalAttribute
ConditionString=Debug

Attributes applied to Main:
System.STAThreadAttribute
System.CLSCompliantAttribute
IsCompliant=True

Attributes applied to .ctor: None
c#的可空类型不是基本类型,当我们定义一个可空类型时,编译出来的仍然是个类,下面看一下这个类的定义:
[Serializable, StructLayout(LayoutKind.Sequential)]

public struct Nullable<T> where T : struct ...{

private Boolean hasValue = false; // Assume null
internal T value = default(T);

public Nullable(T value) ...{
this.Value = value;
this.hasValue = true;
}

public Boolean HasValue ...{ get ...{ return hasValue; } }

public T Value ...{

get ...{

if (!hasValue) ...{
throw new InvalidOperationException(
"Nullable object must have a value.");
}
return value;
}
}

public T GetValueOrDefault() ...{ return value; }

public T GetValueOrDefault(T defaultValue) ...{
if (!HasValue) return defaultValue;
return value;
}

public override Boolean Equals(Object other) ...{
if (!HasValue) return (other == null);
if (other == null) return false;
return value.Equals(other);
}

public override int GetHashCode() ...{
if (!HasValue) return 0;
return value.GetHashCode();
}

public override String ToString() ...{
if (!HasValue) return "";
return value.ToString();
}

public static implicit operator Nullable<T>(T value) ...{
return new Nullable<T>(value);
}

public static explicit operator T(Nullable<T> value) ...{
return value.Value;
}
}
在c#中我们可以这样定义:Nullable<int> x=5;也可以int? x=5;后一种写法更简便。这里我们看到了一个?,c#还定义了一个两个??的操作符。比如我们写:string filename=GetFileName()??"Default" 这个意思就是如果??前面的值不为null就返回前面的值,如果为空就返回后面的值。其实我们可以用三元操作符改写上面的式子:string filename=GetFileName()==null?GetFileName():"Default" 只不过这样写没有上面的那一种简便。
我们可以对可空类型进行装拆箱操作,可以进行接口调用操作:
Int32? n = 5;
Int32 result = ((IComparable) n).CompareTo(5); // Compiles & runs OK
Console.WriteLine(result); // 0
还有当我们调用GetType方法时它返回的可不是System.Nullable<T>哦,看一下:
Int32? x = 5;
// The line below displays "System.Int32"; not "System.Nullable<Int32>"
Console.WriteLine (x.GetType());