ฉันรู้ว่านี่เป็นคำถามเก่า แต่เหตุผลหนึ่งที่ถูกต้องมากที่จะใช้คลาสเป็น namespace (ไม่ใช่แบบคงที่ที่) คือ C # ไม่สนับสนุนความหมายของ namespaces พารามิเตอร์หรือทั่วไป ฉันเขียนโพสต์บล็อกในหัวข้อนี้มากที่นี่: http://tyreejackson.com/generics-net-part5-generic-namespaces/http://tyreejackson.com/generics-net-part5-generic-namespaces/
สรุปสาระสำคัญของมันคือเมื่อใช้ generics เพื่อนามธรรม swaths ขนาดใหญ่ของรหัสรหัสสำเร็จรูปบางครั้งก็จำเป็นต้องใช้พารามิเตอร์ทั่วไปหลายรายการระหว่างชั้นเรียนที่เกี่ยวข้องและอินเทอร์เฟซ วิธีทั่วไปในการทำเช่นนี้คือการกำหนดพารามิเตอร์ทั่วไปข้อ จำกัด และทั้งหมดในแต่ละอินเตอร์เฟสและลายเซ็นคลาส เมื่อเวลาผ่านไปสิ่งนี้อาจนำไปสู่การแพร่กระจายของพารามิเตอร์และข้อ จำกัด ไม่ต้องพูดถึงอย่างต่อเนื่องต้องมีคุณสมบัติประเภทที่เกี่ยวข้องโดยการส่งต่อพารามิเตอร์ประเภทจากประเภทหนึ่งไปยังข้อโต้แย้งประเภทของประเภทที่เกี่ยวข้อง
การใช้คลาส 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
กับList<T>
ในขนาดที่ใหญ่กว่า