นอกเหนือจากเหตุผลอื่น ๆ ที่ระบุไว้ข้างต้นแล้วยังมีอีกเหตุผลหนึ่งที่ฉันคิดได้ว่าไม่เพียง แต่จะใช้คลาสที่ซ้อนกันเท่านั้น สำหรับผู้ที่ทำงานกับคลาสทั่วไปหลายคลาสที่ใช้พารามิเตอร์ประเภททั่วไปเหมือนกันความสามารถในการประกาศเนมสเปซทั่วไปจะมีประโยชน์อย่างยิ่ง น่าเสียดายที่. Net (หรืออย่างน้อย C #) ไม่สนับสนุนแนวคิดของเนมสเปซทั่วไป ดังนั้นเพื่อให้บรรลุเป้าหมายเดียวกันเราสามารถใช้คลาสทั่วไปเพื่อบรรลุเป้าหมายเดียวกันได้ ใช้คลาสตัวอย่างต่อไปนี้ที่เกี่ยวข้องกับเอนทิตีตรรกะ:
public class BaseDataObject
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
where tDataObject : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
where tBusiness : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataAccess : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}
public class BaseDataObjectList
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
:
CollectionBase<tDataObject>
where tDataObject : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
where tBusiness : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataAccess : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}
public interface IBaseBusiness
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
where tDataObject : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
where tBusiness : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataAccess : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}
public interface IBaseDataAccess
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
where tDataObject : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
where tBusiness : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
where tDataAccess : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}
เราสามารถลดความซับซ้อนของลายเซ็นของคลาสเหล่านี้โดยใช้เนมสเปซทั่วไป (ดำเนินการผ่านคลาสที่ซ้อนกัน):
public
partial class Entity
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
where tDataObject : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObject
where tDataObjectList : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObjectList, new()
where tBusiness : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseBusiness
where tDataAccess : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseDataAccess
{
public class BaseDataObject {}
public class BaseDataObjectList : CollectionBase<tDataObject> {}
public interface IBaseBusiness {}
public interface IBaseDataAccess {}
}
จากนั้นด้วยการใช้คลาสบางส่วนตามที่ Erik van Brakel แนะนำในความคิดเห็นก่อนหน้านี้คุณสามารถแยกคลาสออกเป็นไฟล์ที่ซ้อนกันแยกกันได้ ฉันขอแนะนำให้ใช้ส่วนขยาย Visual Studio เช่น NestIn เพื่อรองรับการซ้อนไฟล์คลาสบางส่วน ซึ่งทำให้สามารถใช้ไฟล์คลาส "เนมสเปซ" เพื่อจัดระเบียบไฟล์คลาสที่ซ้อนกันในโฟลเดอร์ได้เช่นกัน
ตัวอย่างเช่น:
Entity.cs
public
partial class Entity
<
tDataObject,
tDataObjectList,
tBusiness,
tDataAccess
>
where tDataObject : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObject
where tDataObjectList : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObjectList, new()
where tBusiness : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseBusiness
where tDataAccess : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseDataAccess
{
}
Entity.BaseDataObject.cs
partial class Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
public class BaseDataObject
{
public DataTimeOffset CreatedDateTime { get; set; }
public Guid CreatedById { get; set; }
public Guid Id { get; set; }
public DataTimeOffset LastUpdateDateTime { get; set; }
public Guid LastUpdatedById { get; set; }
public
static
implicit operator tDataObjectList(DataObject dataObject)
{
var returnList = new tDataObjectList();
returnList.Add((tDataObject) this);
return returnList;
}
}
}
Entity.BaseDataObjectList.cs
partial class Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
public class BaseDataObjectList : CollectionBase<tDataObject>
{
public tDataObjectList ShallowClone()
{
var returnList = new tDataObjectList();
returnList.AddRange(this);
return returnList;
}
}
}
Entity.IBaseBusiness.cs
partial class Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
public interface IBaseBusiness
{
tDataObjectList Load();
void Delete();
void Save(tDataObjectList data);
}
}
Entity.IBaseDataAccess.cs
partial class Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
public interface IBaseDataAccess
{
tDataObjectList Load();
void Delete();
void Save(tDataObjectList data);
}
}
ไฟล์ใน Visual Studio Solution Explorer จะถูกจัดระเบียบดังนี้:
Entity.cs
+ Entity.BaseDataObject.cs
+ Entity.BaseDataObjectList.cs
+ Entity.IBaseBusiness.cs
+ Entity.IBaseDataAccess.cs
และคุณจะใช้เนมสเปซทั่วไปดังต่อไปนี้:
User.cs
public
partial class User
:
Entity
<
User.DataObject,
User.DataObjectList,
User.IBusiness,
User.IDataAccess
>
{
}
User.DataObject.cs
partial class User
{
public class DataObject : BaseDataObject
{
public string UserName { get; set; }
public byte[] PasswordHash { get; set; }
public bool AccountIsEnabled { get; set; }
}
}
User.DataObjectList.cs
partial class User
{
public class DataObjectList : BaseDataObjectList {}
}
User.IBusiness.cs
partial class User
{
public interface IBusiness : IBaseBusiness {}
}
User.IDataAccess.cs
partial class User
{
public interface IDataAccess : IBaseDataAccess {}
}
และไฟล์จะถูกจัดระเบียบในตัวสำรวจโซลูชันดังนี้:
User.cs
+ User.DataObject.cs
+ User.DataObjectList.cs
+ User.IBusiness.cs
+ User.IDataAccess.cs
ข้างต้นเป็นตัวอย่างง่ายๆของการใช้คลาสภายนอกเป็นเนมสเปซทั่วไป ฉันได้สร้าง "เนมสเปซทั่วไป" ที่มีพารามิเตอร์ประเภท 9 รายการขึ้นไปในอดีต การต้องให้พารามิเตอร์ประเภทเหล่านั้นซิงโครไนซ์กับเก้าประเภทที่ทุกคนจำเป็นต้องรู้ว่าพารามิเตอร์ประเภทนั้นน่าเบื่อโดยเฉพาะอย่างยิ่งเมื่อเพิ่มพารามิเตอร์ใหม่ การใช้เนมสเปซทั่วไปทำให้โค้ดนั้นสามารถจัดการและอ่านได้ง่ายขึ้น