나는 이것이 오래된 질문이라는 것을 알고 있지만 클래스를 네임 스페이스 (정적하지 않은 클래스)로 사용하는 매우 유효한 이유 중 하나는 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>
에 해당 합니다.