У меня есть иерархия классов / интерфейсов. На стороне интерфейса у меня есть
IQuery
ISelect (inherits IQuery)
IUpdate (inherits IQuery)
etc
На стороне класса у меня есть
QueryBase (implements IQuery)
SelectQuery (implements ISelect)
UpdateQuery (implements IUpdate)
etc
Очевидно, например, что и классы Update, и классы Select совместно используют предложение WHERE, но только функция Select имеет функциональность GROUP BY, поэтому в идеале, если создается запрос на обновление, свободный интерфейс не будет предоставлять доступ к функциональности GROUP BY, но будет делать, если создается SelectQuery.
например, в условиях свободного интерфейса
var/Dim select = New SelectQuery() <- returns ISelect explicit
.AddColumn(....) <- returns ISelect explicit
.AddWhere(....) <- returns ISelect inferred
.AddGroupBy(....) <- returns ISelect explicit
var/Dim update = New UpdateQuery() <- returns IUpdate explicit
.AddSet(....) <- returns IUpdate explicit
.AddWhere(....) <- returns IUpdate inferred
Я не уверен, как реализовать функцию AddWhere.
Ранее я объявил функцию AddWhere в интерфейсе IQuery как
Function AddWhere(ByVal condition As ICriterion) As IQuery
IQuery AddWhere(ICriterion condition)
но из-за того, что он возвращал IQuery, я терял преимущества вывода типов и поэтому, как только свободный интерфейс был приведен к IQuery, если бы это был созданный запрос Select, у меня больше не было бы доступа к например, метод AddGroupBy.
Итак, я попытался реализовать его как метод расширения с помощью обобщений
<Extension>
Public Function AddWhere(Of T As IQuery)(Byval this as T, Byval condition as Condition) as T
this.SetWhere(condition)
Return Me
End Function
public T AddWhere<T>(T @this, Condition condition) where T : IQuery
{
@this.SetWhere(condition);
return this;
}
с методом Friend (внутренним) SetWhere в QueryBase, чтобы разрешить мне обновить предложение WHERE. Однако, поскольку универсальный ограничен IQuery, он не найдет SetWhere. Однако, если я ограничу как QueryBase, то, очевидно, компилятор выдаст колебания, говоря, что ISelect не может найти метод AddWhere.
Мне кажется, что я не совсем правильно понял цепочку наследования или реализации интерфейса для достижения моих целей.
(надеюсь, это понятно !!)
Буду признателен, если кто-нибудь подскажет, где я ошибаюсь с точки зрения реализации метода расширения, или как мне лучше структурировать мою иерархию классов / интерфейсов.