Возникли проблемы с наследованием и обобщениями в C#

#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».

Я что-то упускаю?