#c# #generics #inheritance #syntax #constructor
#c# #дженерики #наследование #синтаксис #конструктор
Вопрос:
Я рассмотрел ряд вопросов, связанных с определением универсального класса, который наследует базовый класс, но не видел этого случая. (Извините, если я это пропустил.)
Мой класс — это универсальный класс. Он наследует конкретный базовый класс. Конструктор для базового класса принимает аргументы.
Я могу заставить определение класса работать, если исключу общую спецификацию следующим образом:
public class DataItemType : DataItem
{
public DataItemType(string sNameArg, string sAddressArg, bool nWriteAllowedArg)
: base(sNameArg, sAddressArg, nWriteAllowedArg)
{
}
}
Вот определение с общей спецификацией.
public class DataItemType<TValue> : DataItem where TValue : struct
{
public DataItemType<TValue>(string sNameArg, string sAddressArg, bool nWriteAllowedArg)
: base(sNameArg, sAddressArg, nWriteAllowedArg)
{
}
}
В строке определения класса IDE жалуется, что не указан аргумент, соответствующий требуемому формальному параметру sNameArg базового класса. IDE предлагает создать конструктор. Но когда это происходит, синтаксис терпит неудачу. (Вставленный конструктор, похоже, тоже не имеет никакого смысла, как бы то ни было.)
Комментарии:
1. Пропустить
<TValue>
изDataItemType
конструктора
Ответ №1:
Просто удалите <TValue>
из строки конструктора в универсальном классе:
public class DataItem
{
public DataItem(string sNameArg, string sAddressArg, bool nWriteAllowedArg) {}
}
public class DataItemType<TValue> : DataItem where TValue : struct
{
public DataItemType(string sNameArg, string sAddressArg, bool nWriteAllowedArg)
: base(sNameArg, sAddressArg, nWriteAllowedArg)
{
}
}
TValue
В универсальном классе используется для параметров, которые вы передаете функциям или возвращаете значения. Но не в конструкторе.
Вы путаете его с добавлением функции <>
after a . Добавление его туда означает, что сама функция является универсальной и может принимать разные типы.
- Общие сведения о методах см. в разделе Общие методы
- Для обобщений в классах см. Общие классы
Если, например, вы хотите получить параметр в конструкторе из универсального типа, то:
public class DataItemType<TValue> : DataItem where TValue : struct
{
public DataItemType(TValue someParameter, string sNameArg, string sAddressArg, bool nWriteAllowedArg)
: base(sNameArg, sAddressArg, nWriteAllowedArg)
{
}
//Note that as in the constructor you can use this generic type for the function
public void SomeFunction(TValue value) { }
//Or define a new generic type which will be only in the scope of this function
public void SomeOtherFunction<TValue2>(TValue2 value2) { }
}
Комментарии:
1. Вы правы. Я несколько раз читал страницы, посвященные универсальным классам и универсальным методам. Я взял общий параметр в определении класса как часть имени класса. Конструктор должен иметь то же имя, что и класс, поэтому я помещаю общий параметр в имя конструктора. Я не вижу в онлайн-руководстве по программированию ничего, что могло бы исправить это заблуждение. Спецификация C # не очевидна в этом вопросе, imo.
2. @GregoryAshmore — Я вижу, откуда происходит недоразумение 🙂 Рад, что вам удалось решить это с помощью моего ответа