Bunun eski bir soru olduğunu biliyorum, ancak bir sınıfı ad alanı olarak kullanmanın çok geçerli bir nedeni (statik olmayan bir tane) C # parametrik veya genel ad alanlarının tanımını desteklemiyor. Bu konuyla ilgili bir blog yazısı buraya yazdım : http://tyreejackson.com/generics-net-part5-generic-namespaces/ .
Bunun temel amacı, büyük kazan plakası kodlarını tasarlamak için jenerik kullanırken, bazen ilgili sınıflar ve arayüzler arasında çoklu jenerik parametreleri paylaşmak gerekir. Bunu yapmanın geleneksel yolu, genel parametreleri, kısıtlamaları ve her bir arayüzdeki ve sınıf imzasındaki tüm parametreleri yeniden tanımlamak olacaktır. Zamanla bu, tür parametrelerini bir türden ilgili türün tür argümanlarına ileterek, ilgili türlerin sürekli olarak nitelendirilmesi gerekmediğinden, parametrelerin ve kısıtlamaların çoğalmasına neden olabilir.
Dış bir Genel sınıf kullanmak ve ilgili türlerin içine yerleştirmek, kodu önemli ölçüde KURUTABİLİR ve soyutlamasını basitleştirir. Daha sonra, parametrik ad alanı sınıfını, tüm somut ayrıntıları sağlayan somut bir uygulama ile türetebilirsiniz.
İşte önemsiz bir örnek:
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);
}
}
Bu gibi kullanılır:
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 {}
}
Bunun gibi türevleri tüketin:
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);
}
}
Türleri bu şekilde yazmanın faydası, sınıf güvenliği ve soyut sınıflarda türlerin daha az kullanılmasıdır. Onun daha büyük bir ölçekte ArrayList
vs eşdeğeri List<T>
.