我知道这是一个古老的问题,但是使用类作为名称空间(当时是非静态名称空间)的一个非常合理的理由是C#不支持参数或通用名称空间的定义。我在这里写了一篇关于这个主题的博客文章:http://tyreejackson.com/generics-net-part5-generic-namespaces/。
其要点是,当使用泛型来抽象大量样板代码时,有时有必要在相关类和接口之间共享多个泛型参数。这样做的常规方法是在每个接口和类签名中重新定义通用参数,约束以及所有参数。随着时间的流逝,这可能导致参数和约束的激增,更不用说不断地通过将类型参数从一种类型转发到相关类型的类型实参来限定相关类型。
使用外部Generic类并在其中嵌套相关类型可以极大地使代码干燥并简化其抽象。然后,可以使用提供所有具体细节的具体实现派生参数化名称空间类。
这是一个简单的示例:
public class Entity
<
TEntity,
TDataObject,
TDataObjectList,
TIBusiness,
TIDataAccess,
TIdKey
>
where TEntity : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>, subclassed
where TDataObject : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.BaseDataObject, subclassed
where TDataObjectList : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.BaseDataObjectList, subclassed
where TIBusiness : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.IBaseBusiness
where TIDataAccess : Entity<TEntity, TDataObject, TDataObjectList, TIBusiness, TIDataAccess, TIdKey>.IBaseDataAccess
{
public class BaseDataObject
{
public TIdKey Id { get; set; }
}
public class BaseDataObjectList : Collection<TDataObject> {}
public interface IBaseBusiness
{
TDataObject LoadById(TIdKey id);
TDataObjectList LoadAll();
void Save(TDataObject item);
void Save(TDataObjectList items);
void DeleteById(TIdKey id);
bool Validate(TDataObject item);
bool Validate(TDataObjectList items);
}
public interface IBaseDataAccess
{
TDataObject LoadById(TIdKey id);
TDataObjectList LoadAll();
void Save(TDataObject item);
void Save(TDataObjectList items);
void DeleteById(TIdKey id);
}
}
像这样使用:
public class User
:
Entity
<
User,
User.DataObject,
User.DataObjectList,
User.IBusiness,
User.IDataAccess,
Guid
>
{
public class DataObject : BaseDataObject
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class DataObjectList : BaseDataObjectList {}
public interface IBusiness : IBaseBusiness
{
void DeactivateUserById(Guid id);
}
public interface IDataAcccess : IBaseDataAccess {}
}
消耗这样的导数:
public class EntityConsumer
{
private User.IBusiness userBusiness;
private Permission.IBusiness permissionBusiness;
public EntityConsumer(User.IBusiness userBusiness, Permission.IBusiness permissionBusiness) { /* assign dependencies */ }
public void ConsumeEntities()
{
var users = new User.DataObjectList();
var permissions = this.permissionBusiness.LoadAll();
users.Add
(new User.DataObject()
{
// Assign property values
});
this.userBusiness.Save(users);
}
}
以这种方式编写类型的好处是增加了类型安全性,并减少了抽象类中类型的转换。相当于ArrayList
vs List<T>
在更大范围内。