Saya tahu bahwa ini adalah pertanyaan lama, tetapi satu alasan yang sangat valid untuk menggunakan kelas sebagai namespace (yang tidak statis pada saat itu) adalah bahwa C # tidak mendukung definisi ruang nama parametrik atau generik. Saya telah menulis posting blog tentang topik ini di sini: http://tyreejackson.com/generics-net-part5-generic-namespaces/ .
Inti dari itu adalah, ketika menggunakan obat generik untuk abstrak petak besar kode boilerplate, kadang-kadang diperlukan untuk berbagi beberapa parameter generik antara kelas dan antarmuka terkait. Cara konvensional untuk melakukan ini adalah dengan mendefinisikan kembali parameter generik, batasan dan semua di setiap antarmuka dan kelas tanda tangan. Seiring waktu hal ini dapat menyebabkan proliferasi parameter dan kendala belum lagi harus terus-menerus memenuhi syarat untuk jenis terkait dengan meneruskan parameter jenis dari satu jenis ke jenis argumen dari jenis terkait.
Menggunakan kelas Generic luar dan menumpuk jenis terkait di dalamnya dapat secara dramatis MENINGGALKAN kode dan menyederhanakan abstraksinya. Seseorang kemudian dapat menurunkan kelas namespace parametrik dengan implementasi konkret yang memasok semua detail konkret.
Berikut ini adalah contoh sepele:
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);
}
}
Digunakan seperti ini:
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 {}
}
Konsumsi turunannya seperti ini:
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);
}
}
Manfaat menulis tipe dengan cara ini adalah menambahkan keamanan tipe dan mengurangi casting tipe dalam kelas abstrak. Ini setara dengan ArrayList
vs List<T>
pada skala yang lebih besar.