#c# #generics #inheritance
#c# #обобщения #наследование
Вопрос:
У меня есть класс, и я объявляю его следующим образом:
public class WhereOrCondition<T> : WhereCondition<T>
Универсальный тип T
одинаков для обоих классов. Я не уверен, как правильно объявлять мои классы, чтобы универсальный тип, используемый для WhereOrCondition
, также использовался в WhereCondition
.
Объявление моего класса таким образом выдает мне следующую ошибку:
Error 1 The type 'T' cannot be used as type parameter 'T' in the generic type or method 'BrainStorm.WhereCondition<T>'. There is no boxing conversion or type parameter conversion from 'T' to 'BrainStorm.DatabaseObject'.
Есть идеи о том, как я могу правильно объявить свой класс?
Редактировать
WhereCondition
Класс объявлен следующим образом:
public class WhereCondition<T> : IEnumerable<KeyValuePair<string, object>> where T : DatabaseObject
Комментарии:
1. Что
BrainStorm.DatabaseObject
такое и как вы создаете экземпляр универсального подкласса в своем вызывающем коде?2. каково определение WhereCondition<T>?
3. Случайно
WhereCondition
не ограниченwhere T: BrainStorm.DatabaseObject
…? Если это так, другим тоже нужно такое же ограничение.4. Я добавил объявление класса для whereecondition
Ответ №1:
Вам нужно поставить то же условие where WhereOrCondition<T>
, чтобы оно выглядело как
public class WhereOrCondition<T> : WhereCondition<T> where T: DatabaseObject
Правило заключается в том, что предложение where для подкласса должно быть таким же или более ограничительным, чем предложение where для базового класса.
То, что это говорит, WhereOrCondition<T>
относится WhereCondition<T>
к подклассу и T
должно быть DatabaseObject
(или подклассом).
Ваш код в комментарии public class WhereAndCondition<T> where T: WhereCondition<T>
— это нечто совершенно иное. Это говорит о том, что T
должно быть WhereCondition<T>
, что не может быть правдой.
Комментарии:
1. Извините, я все еще немного сбит с толку. Прямо сейчас у меня это так
public class WhereAndCondition<T> where T: WhereCondition<T>
. Но это все еще говорит о том, что это неправильно.2. Обновлено @user489041 (не уверен, откуда
WhereAndCondition<T>
взялось)
Ответ №2:
Добавление кода для ответа Рэя:
public class WhereOrCondition<T> : WhereCondition<T> where T : DatabaseObject { }
public class WhereCondition<T> : IEnumerable<KeyValuePair<string, object>> where T : DatabaseObject
{
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { }
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class DatabaseObject { }
Ответ №3:
У вас недостаточно кода, чтобы кто-либо действительно мог определить, чего вы пытаетесь достичь. Позвольте мне проиллюстрировать.
Если вы имеете в виду «когда я создаю производный класс, а затем ‘приведу’ его в качестве родительского класса, я хочу, чтобы T было равно», то имеющийся у вас на данный момент код, похоже, соответствует этому показателю. Предположим …
public class WhereCondition<T>
{
}
public class WhereOrCondition<T> : WhereCondition<T>
{
}
public class DatabaseObject
{
public int Id { get; set; }
}
Теперь вы можете использовать родительские и дочерние классы и, в большинстве случаев, выполнять приведение вверх и вниз сколько душе угодно. И внутренний объект будет таким же.
Единственное, что я могу придумать, что может вызвать проблему, это если вы на самом деле не сохраняете «общие» вещи и вы ввели T в одном из классов, добавив «где T: ObjectType».
Я что-то упускаю?