在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 上下文关键字指定的。下表列出了六种类型的约束:
使用约束的原因 如果要检查泛型列表中的某个项以确定它是否有效,或者将它与其他某个项进行比较,则编译器必须在一定程度上保证它需要调用的运算符或方法将受到客户端代码可能指定的任何类型参数的支持。这种保证是通过对泛型类定义应用一个或多个约束获得的。例如,基类约束告诉编译器:仅此类型的对象或从此类型派生的对象才可用作类型参数。一旦编译器有了这个保证,它就能够允许在泛型类中调用该类型的方法。约束是使用上下文关键字 where 应用的。 [转] 泛型约束基本上有五种:
public class MyClass2<T>
public class MyClass<T>
public class MyClass3<T>
public class MyClass4<T>
public class MyClass5<T> using System; using System.Collections.Generic; using System.Text; using System.Data.Common; using Dare.Utilities.Data; using Dare.DN.Components; using System.Data; using log4net.Core; namespace Dare.DN.Data { public abstract class DataProviderTemplate<Entity, Key> : DataProviderBase where Entity : class, IEntity, IEntity<Key>,new() where Key : struct { protected List<EntityRelationDataProvider<Entity, Key>> relationDataProviders; public DataProviderTemplate() { relationDataProviders = new List<EntityRelationDataProvider<Entity, Key>>(); } #region 关系操作方法 public void AddRelationDataProviders(params EntityRelationDataProvider<Entity, Key>[] providers) { relationDataProviders.AddRange(providers); } protected virtual void InsertRelations(TransactionManager manager, DbCommand cmd, IEnumerable<Entity> entities) { if (entities == null) return; foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Insert(manager, cmd, entities); } } protected virtual void InsertRelations(TransactionManager manager, DbCommand cmd, params Entity[] entities) { InsertRelations(manager, cmd, (IEnumerable<Entity>)entities); } protected virtual void UpdateRelations(TransactionManager manager, DbCommand cmd, IEnumerable<Entity> entities) { if (entities == null) return; foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Update(manager, cmd, entities); } } protected virtual void UpdateRelations(TransactionManager manager, DbCommand cmd, params Entity[] entities) { UpdateRelations(manager, cmd, (IEnumerable<Entity>)entities); } protected virtual void DeleteRelations(TransactionManager manager, DbCommand cmd, IEnumerable<Key> keys) { if (keys == null) return; foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Delete(manager, cmd, keys); } } protected virtual void DeleteRelations(TransactionManager manager, DbCommand cmd, params Key[] keys) { DeleteRelations(manager, cmd, (IEnumerable<Key>)keys); } protected virtual void DeleteRelations(TransactionManager manager, DbCommand cmd, string whereClause) { string whereCluase = ProcessWhereClause(whereClause); foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Delete(manager, cmd, whereClause); } } protected virtual void CleanRelations(DbCommand cmd) { foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Clean(cmd); } } protected virtual void RetrieveRelations(TransactionManager manager, DbCommand cmd, IEnumerable<Entity> entities) { if (entities == null) return; foreach (EntityRelationDataProvider<Entity, Key> provider in relationDataProviders) { provider.Retrieve(manager, cmd, entities); } } protected virtual void RetrieveRelations(TransactionManager manager, DbCommand cmd, params Entity[] entities) { RetrieveRelations(manager, cmd, (IEnumerable<Entity>)entities); } #endregion #region 基本操作方法 public abstract void Insert(TransactionManager manager, Entity entity); public abstract void Import(TransactionManager manager, IEnumerable<Entity> entities); public abstract void Update(TransactionManager manager, Entity entity); public abstract void Delete(TransactionManager manager, Key key); public abstract void DeleteAll(TransactionManager manager, string whereClause); public abstract Entity Get(TransactionManager manager, Key key); public virtual List<Entity> GetAll(TransactionManager manager, string whereClause, string orderBy) { return GetPaged(manager, whereClause, orderBy, -1, -1); } public abstract List<Entity> GetPaged(TransactionManager manager, string whereClause, string orderBy, int pageIndex, int pageSize); public abstract int GetCount(TransactionManager manager, string whereClause); public abstract long GetVersion(TransactionManager manager, string whereClause); public abstract Entity Fill(IDataReader reader, Entity entity); #endregion #region 内部操作模板方法 protected virtual int InternalExecuteNonQuery(TransactionManager manager, string sql, params DbParameter[] parameters) { int result = 0; Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); //执行 result = cmd.ExecuteNonQuery(); /*------------------------------数据库SQL操作结束----------------------------------*/ }); return result; } protected virtual List<Entity> InternalGetList(TransactionManager manager, string sql, params DbParameter[] parameters) { List<Entity> list = new List<Entity>(); Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); //执行获取实体集 using (IDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { list.Add(Fill(reader, null)); } } //获取关系对象 RetrieveRelations(mgr, cmd, list); /*------------------------------数据库SQL操作结束----------------------------------*/ }); return list; } protected virtual List<Key> InternalGetKeyList(TransactionManager manager, string sql, params DbParameter[] parameters) { List<Key> list = new List<Key>(); Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); //执行获取实体集 using (IDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { list.Add((Key)Convert.ChangeType(reader.GetValue(0), typeof(Key))); } } /*------------------------------数据库SQL操作结束----------------------------------*/ }); return list; } protected virtual T InternalGetValue<T>(TransactionManager manager, string sql, T defaultValue, params DbParameter[] parameters) { T val = default(T); Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); //执行获取实体集 object objValue = cmd.ExecuteScalar(); val = DbConvert.ChangeType<T>(objValue, defaultValue); /*------------------------------数据库SQL操作结束----------------------------------*/ }); return val; } protected virtual List<T> InternalGetValueList<T>(TransactionManager manager, string sql, T defaultValue, params DbParameter[] parameters) { List<T> list = new List<T>(); Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sql; cmd.Parameters.AddRange(parameters); //执行获取实体集 using (IDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { list.Add(DbConvert.ChangeType<T>(reader[0], defaultValue)); } } /*------------------------------数据库SQL操作结束----------------------------------*/ }); return list; } public delegate T FillEntityHandler<T>(IDataReader reader, T entity); public delegate void AfterRetrievedEntityListHandler<T>(TransactionManager mgr, DbCommand cmd, IEnumerable<T> entities); protected T InternalGet<T>(TransactionManager manager, string sqlGet, FillEntityHandler<T> fillEntityHandler, AfterRetrievedEntityListHandler<T> afterRetrieveHandler, params DbParameter[] parameters) where T : class { if (fillEntityHandler == null) throw new ArgumentNullException("fillEntityHandler", "实体数据填充调用方法不能为空!"); T entity = null; Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取SQL语句 cmd.CommandText = sqlGet; cmd.Parameters.AddRange(parameters); //执行获取实体 using (IDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { entity = fillEntityHandler(reader, null); } } if (afterRetrieveHandler != null && entity != null) { afterRetrieveHandler(mgr, cmd, new T[] { entity }); } /*------------------------------数据库SQL操作结束----------------------------------*/ }); return entity; } protected Entity InternalGet(TransactionManager manager, string sqlGet, params DbParameter[] parameters) { return InternalGet<Entity>(manager, sqlGet, Fill, RetrieveRelations, parameters); } protected List<Entity> InternalGetPaged(TransactionManager manager, string sqlGetPaged, string sqlGetCount, int pageIndex, int pageSize, out int totalCount, params DbParameter[] parameters) { return InternalGetPaged<Entity>(manager, sqlGetPaged, sqlGetCount, Fill, RetrieveRelations, pageIndex, pageSize, out totalCount, parameters); } protected List<T> InternalGetPaged<T>(TransactionManager manager, string sqlGetPaged, string sqlGetCount, FillEntityHandler<T> fillEntityHandler, AfterRetrievedEntityListHandler<T> afterRetrieveHandler, int pageIndex, int pageSize, out int totalCount, params DbParameter[] parameters) where T:class { if (fillEntityHandler == null) throw new ArgumentNullException("fillEntityHandler", "实体数据填充调用方法不能为空!"); List<T> list = null; int count = 0; Execute(manager, delegate(TransactionManager mgr, DbCommand cmd) { /*------------------------------数据库SQL操作开始----------------------------------*/ //获取总记录数 cmd.CommandText = sqlGetCount; cmd.Parameters.AddRange(parameters); count = Convert.ToInt32(cmd.ExecuteScalar()); if (count > 0) { //确定分页和获取记录的数量 if (pageIndex < 0 || pageSize <= 0) { list = new List<T>(count); //不用分页 } else if (count > (pageIndex-1) * pageSize) { list = new List<T>(pageSize); //使用分页 } else { list = new List<T>(0); //分页超过记录数量,输出空记录集 return; } //获取记录集 cmd.CommandText = sqlGetPaged; using (IDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { list.Add(fillEntityHandler(reader, null)); } } if (afterRetrieveHandler != null) { afterRetrieveHandler(mgr, cmd, list); } } else { list = new List<T>(0); //无记录返回空记录集 return; } /*------------------------------数据库SQL操作结束----------------------------------*/ }); totalCount = count; return list; } #endregion } } |
|