Реализация абстрактной универсальной функции

У меня проблемы с абстрактным универсальным методом.

Определение абстрактного метода

protected abstract T InitEntity<T>(ref NpgsqlDataReader reader) where T : BaseEntity, new();

Выполнение

protected override EUser InitEntity<EUser>(ref NpgsqlDataReader reader) {

У меня проблема с классом EUser в функции переопределения. Похоже, что функция рассматривает EUser как Generic T, где доступны только функции BaseEntity. ERole — это еще один класс, который реализует BaseEntity, и я могу использовать все функциональные возможности этого объекта в функции. Если я хочу использовать EUser, мне нужно вводить его в EUser каждый раз, когда я хочу использовать функцию, которой нет в родительской BaseEntity. Моя цель состояла в том, чтобы передать средство чтения данных дочернему классу и заставить его заполнить необходимую информацию, но это оказалось проблематичным. Я не хочу тратить много накладных расходов на преобразование всего в дочернем классе.

Это не то же самое, что с общими классами. Если я реализую дочерний универсальный класс, я могу указать EUser для родительского класса и по-прежнему иметь полную функциональность этого объекта.

У кого-нибудь еще была проблема с этим, или я неправильно реализую абстрактную универсальную функцию?

Родительская функция начинается так:

protected T Select<T>(string sql, params NpgsqlParameter []) {

Затем родительский класс вызывает функцию следующим образом:

T entity = InitEntity<T>(ref dr);

Проблема должна заключаться в том, что T используется для создания метода подкласса, поэтому даже если метод подкласса будет принимать и использовать только EUser. Он по-прежнему рассматривает его как Generic T в методе. У вас есть предложения?

Все это вызвано тем, что у меня есть родительский класс, в котором есть несколько частных полей, которые я не хочу использовать ни в каких дочерних классах. Общий метод InitEntity использует некоторые из этих закрытых полей. Из-за этого я играю с общими методами. Вероятно, мне просто нужно переосмыслить свою реализацию и согласиться с дочерними универсальными классами.

Редактировать:

Похоже, что с универсальными методами в C# тип переменной определяется при вызове функции. Похоже, вы не можете определить этот тип дальше на функциональном уровне без преобразования основного типа. Если вы попытаетесь реализовать тип в функции подкласса, как это сделал я, все будет компилироваться и функционировать, но ваш тип в подклассе по-прежнему будет рассматриваться как тот, который когда-либо был передан. Для моей проблемы, определенной выше, мне просто нужно измените универсальный на уровень класса, а не просто на функцию. Сделать абстрактную универсальную функцию. Дочерняя функция должна сохранить общий T того, что передается, а затем преобразовать его в тело функции.


person Vintle    schedule 27.01.2021    source источник
comment
Где определяется T? Это на уровне класса или на уровне метода? abstract class MyClass<T> или Method<T>()?   -  person Taco タコス    schedule 27.01.2021
comment
Кроме того, можем ли мы получить фрагменты определений классов для BaseEntity, EUser и ERole без содержимого? Просто public abstract class MyClass : ICloneable... { } вещь должна сильно помочь.   -  person Taco タコス    schedule 27.01.2021
comment
Отвечает ли это на ваш вопрос? Удивительно повторяющийся шаблон шаблона и общие ограничения (C#)   -  person Charlieface    schedule 27.01.2021
comment
Является ли родительский класс базовым классом, в котором определен абстрактный метод InitEntity? Если вы вызываете InitEntity из родительского класса, то все, что родительский класс знает о T, это то, что он расширяет BaseEntity. Он не знает, как какие-либо дочерние классы реализовали InitEntity, даже если есть только одна дочерняя реализация, родительский класс этого не знает.   -  person TJ Rockefeller    schedule 27.01.2021