#c# #generics #repository #abstract-class
#c# #общие #репозиторий #абстрактный класс
Вопрос:
я пытаюсь создать общий репозиторий для моего объекта поиска и написать это:
public interface ILookupRepository<T> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, int>
where T: LookUpObject
{
}
ICan...
это интерфейс, который определяет детальную работу для репозитория, таким образом, я могу использовать композицию для определения поведения
я хочу ограничить этот интерфейс только для моего объекта поиска, поэтому я использую where T: LookUpObject
ограничение
это абстрактный класс:
public abstract class LookUpObject<TObject, TKeyType> : IKeyedEntity<TKeyType>
where TObject : class
where TKeyType : struct
{
private TKeyType id;
private string description;
private bool valid;
public TKeyType Id
{
get { return id; }
set { id = value; }
}
public string Description
{
get { return description; }
set { description= value; }
}
public bool Valid
{
get { return valid; }
set { valid= value; }
}
protected LookUpObject()
{
}
}
но я не знаю, как определить ограничения для моего класса репозитория:
я пытаюсь
public interface ILookupRepository<T> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, int>
where T: LookUpObject<T1, TkeyType> where T1: class
where TkeyType: Type
но он не распознает T1
и TkeyType
возможно ли это?
Редактировать
решение @Grax с использованием TkeyType вместо ключа int
public interface ILookupRepository<T, TkeyType> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, TkeyType>
where T : LookUpObject<T, TkeyType>
where TkeyType : struct
Комментарии:
1. Это может быть просто так
T1
, иTKeyType
это должно быть включеноILookupRepository
. Не совсем уверен.
Ответ №1:
Я предполагаю, что вы этого хотите. По сути, это ответ Тайкобба с объединением T и T1, но я также думаю, что вы хотите, чтобы TKeyType был struct , основанный на ограничении, которое вы накладываете на свой абстрактный класс, а не на то, чтобы он буквально наследовал от типа «Type».
public interface ILookupRepository<T, TKeyType> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, int>
where T : LookUpObject<T, TKeyType>
where TKeyType : struct
{
}
Теперь, если ваш «идентификатор» и ваш «ключ» на самом деле являются одним и тем же фрагментом данных, вы можете даже захотеть, чтобы это было так. Это предполагает, что ключ будет иметь тип «int».
public interface ILookupRepository<T> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, int>
where T : LookUpObject<T, int>
{
}
Комментарии:
1. предположение почти правильное, может быть, я буду преобразовывать ICanGetById<T, int> в ICanGetById<T, TKeyType> . Завтра на работе я попытаюсь изменить код вопроса
Ответ №2:
Как указано в комментариях Magus, вы должны определить T1
и TKeyType
в определении интерфейсов, чтобы вы могли передавать типы.
public interface ILookupRepository<T, T1, TkeyType> :
IDisposable,
ICanGetAll<T>,
ICanGetById<T, int>
where T: LookUpObject<T1, TkeyType> where T1: class
where TkeyType: Type
Итак, когда вы реализуете интерфейс, укажите, какие типы:
public MyPersonRepository : ILookupRepository<Person, MyT1Object, MyType>
Ваше определение может быть правильным, но, глядя на то, что вы указали в коде, кажется, что вы дублируете T
и T1
. Если это так, то избавьтесь от T1
него и просто используйте T
вместо этого.
Комментарии:
1. да: T и T1 одинаковы, я подумал, что мне нужно переопределить это