泛型
C#早期使用Object来代表任意类型,运行时强制转换存在安全问题,类型判断影响效率。
public interface IComparable
{
int CompareTo(object other);
}
public class Customer : IComparable
{
public string Name;
public int CompareTo(object right)
{
if(!(right is Customer))
{
throw new ArgumentException("Argument not a customer", "right");
Customer rightCustomer = (Customer)right;
return Name.CompareTo(rightCustomer.Name);
}
}
}
使用泛型能够保证编译器类型安全,并提高应用程序的执行效率。
/// 泛型类, Example<int> e = new Example<int>();
public class Example<T> where T : new() // 泛型约束:struct、class、new()、NameOfBaseClass\NameOfInterface
{
private T t;
}
/// 泛型方法, ExampleFunc.DoSomething(1);
public static ExampleFunc
{
public static T DoSomething(T t)
{
Console.Writeline(t.GetType());
}
}
// 无参数泛型方法使用
static T SomeMethod<T>() where T:new()
{
Console.WriteLine("Typeof T: "+typeof(T));
return new T();
}
使用泛型方法比泛型类更简单,不用显示的指明类型参数。有两种情况必须使用泛型类:
- 类本身需要存放类型参数对象作为其内部状态。(例如List
) - 类实现了泛型接口
需要在到类型参数为值类型还是引用类型的情况下,用default为对象赋初值
///之所以会用到default关键字,
///是因为需要在不知道类型参数为值类型还是引用类型的情况下,为对象实例赋初值。
///考虑以下代码:
class TestDefault<T>
{
public T foo()
{
T t = null; //???
return t;
}
}
///如果我们用int型来绑定泛型参数,那么T就是int型,
///那么注释的那一行就变成了 int t = null;显然这是无意义的。
///为了解决这一问题,引入了default关键字:
class TestDefault<T>
{
public T foo()
{
return default(T);
}
}
C#中的多线程
使用线程池而不是创建线程。如使用ThreadPool.QueueUserWorkItem
当需要检查完成情况、跟踪进度、暂停或取消任务时,使用BackgroundWorker
优先使用lock().需要在不同上下文中释放锁,或者需要给锁加个超时时间时,使用Monitor.Enter(lockTarget)/Monitor.TryEnter(lockTarget, 1000ms)和Monitor.Exit(lockTarget)
未规避死锁问题,规定lock(this)或lock(someclass)都不如为类创建一个同步对象
private object syncHandle = new object();
public void IncrementTotal()
{
lock(syncHandle)
{
//代码省略
}
}
如果程序不需要经常锁定,一种减少同步对象创建的写法:
private object syncHandle;
private object GetSyncHandle()
{
// CompareExchange首先比较syncHandle和null,若为null则创建一个新对象并指派给syncHandle
System.Threading.Interlocked.CompareExchange(ref syncHandle, new object(), null);
return syncHandle
}
public void IncrementTotal()
{
lock(GetSyncHandle())
{
//代码省略
}
}
System.Threading.Interlocked.Increment(ref v);原子自增
System.Threading.Interlocked.Decrement(ref v);原子自减
System.Threading.Interlocked.Exchange(ref T location, T value);原子替换并返回原始值
System.Threading.Interlocked.CompareExchange(ref T location, T value, T comparand);原子比较,若相等则赋新值;不关相等与否都返回原始值
ReaderWriteLockSlim(ReaderWriterLock的改进版);读写锁
28:使用扩展方法增强现有接口
当许多类需要同时实现一个接口时,那么可以考虑在接口中仅定义最小的成员,然后以扩展方法的形式提供其他的方法。
public interface MyInterface
{
void MustDo();
}
public class DoClass : MyInterface
{
public void MustDo()
{
}
}
public static class InterfaceExtentions
{
public static void AroundMustDo(this MyInterface @interface)
{
Console.WriteLine("before must do");
@interface.MustDo();
Console.WriteLine("after must do");
}
}