Есть ли способ сделать то, что я хочу здесь?Использовать тип конкретной реализации в абстрактном базовом классе
Базовый класс определяется следующим образом:
public abstract class BaseClass<TExists>
where TExists : BaseExists
{
// needs to be overridden by child
protected abstract bool Exists(TExists existsData, out /*typeof(this)*/ existingElement); // <- how to have the concrete type here?
// static method to be invoked without any need of an instance
public static bool Exists(TExists existsData, out /*typeof(this)*/ existingElement)
{
var temp; // <-- how to set the type here?
// create a concrete instance
var instance = Activator.CreateInstance(???);
// call the concrete implementation
if(instance.Exists(existsData, out temp))
{
return true;
}
return false;
}
}
И здесь у нас есть некоторые конкретные реализации:
public class ChildClass : BaseClass<ChildClassExists>
{
protected override bool Exists(ChildClassExists exists, out ChildClass existingElement)
{
// do child-related things here
}
}
В конце я хочу использовать его как
ChildClass existing;
if(ChildClass.Exists(new ChildClassExists(), out existing)){
// do things here with the existing element of type 'ChildClass'
}
потому что мне здесь не нужен экземпляр (это скрыто внутри реализации базового класса Exists).
Update # 1
Как реализуется как в промежуточные кадры первого ответа теперь у меня есть:
public static bool Exists<T>(TExists existsModel, out T existingEntityModel)
where T : BaseClass<TExists>
{
var instance = Activator.CreateInstance<T>();
return instance.ExistsInternal(existsModel, out existingEntityModel);
}
protected abstract bool ExistsInternal<T>(TExists createModel, out T existingEntityModel)
where T : BaseClass<TExists>;
Но это вызовет ошибку в конкретной реализации метода ExistsInternal
Невозможно преобразовать тип источника 'ChildClass' в целевой тип 'T'
в переопределение
protected override bool ExistsInternal<T>(ChildClassExists existsData, out T existingElement)
{
existingElement = new ChildClass(); // <-- here the error is thrown
return true;
}
Вам нужно будет добавить еще один общий параметр ('TConcrete'). Но в целом проблема связана с плохим дизайном. Кроме того, вместо 'Activator.CreateInstance()' вы сможете сделать 'новый TConcrete()' (предполагая, что вы сможете добавить ограничение 'new()') – haim770
Вы пробовали 'out TExists existingElement 'и' TExists temp; '? –
@FabioLuz: 'TExists' является базовым типом объекта, содержащего данные для проверки наличия, а не типа объекта, который должен быть возвращен. – KingKerosin