Próbuję utworzyć wspólny interfejs, który pozwoli mi korzystać z metod interakcji z bazą danych. Chcę, aby moja aplikacja biznesowa była w stanie utworzyć instancję dowolnej metodologii połączeń i mieć pewność, że interfejs jest identyczny.Implementowanie ogólnych metod z interfejsu przy użyciu innego interfejsu
Oto uproszczona wersja tego, co próbuję teraz.
Interfejs bazy danych, w którym IElement
to kolejny interfejs definiujący tabelę. Interfejs
public interface IDatabase
{
void setItem(IElement task); //this works fine
List<T> listTasks<T>() where T : IElement; // this doesn't
}
IElement:
public interface IElement
{
int id { get; set; }
}
Realizacja IElement:
public class TaskElement: IElement
{
public int id { get; set; }
public string name {get; set; }
}
Realizacja IDatabase:
public class SQLiteDb: IDatabase
{
public SqLiteDb(SQLiteConnection conn)
{
database = conn;
}
public void setItem(IElement task)
{
// works fine when passed a new TaskElement() which is an implementation of IElement.
database.Insert(task);
}
//it all goes off the rails here
public List<T> listItems<T>() where T : IElement
{
var returnList = new List<IElement>
foreach (var s in database.Table<TaskElement>())
{ returnList.Add(s); }
return returnList;
}
Próbowałem wiele wariacji na ten temat, ale każdy daje mi nową pozwać. Tutaj na przykład są dwa błędy.
1)
typu argumenty dla metody
'SQLiteDb.listTasks<T>()'
nie można wywieść ze stosowania. Spróbuj jawnie określić argumenty typu.
2)
nie można niejawnie przekonwertować typu
'System.Collections.Generic.List<TaskElement>'
do'System.Collections.Generic.List<T>'
Próbowałem zmiany sposobu korzystania z wyraźną typ ale mieli tam problemy. Jeśli używam IElement
(mój ogólny interfejs dla wszystkich elementów), nie mogę zwrócić listy obiektów TaskElement (moja implementacja IElement
), ponieważ nie pasuje ona do typu zwracanego (List<IElement>
), a jeśli zmienię typ zwracany na List<TaskElement>
I "Nie będę już wdrażać interfejsu.
Warto zauważyć, że mogę łatwo uruchomić to, jeśli przestanę używać interfejsu i generycznych, ale wydaje mi się to idealną sytuacją do korzystania z interfejsu. Może staram się włożyć dużo rzeczy do interfejsu, gdy inna aplikacja (jak dziedziczenie bezpośrednie) może być lepsza?
Pytanie
Jak mogę zaimplementować interfejs z ogólnej wartości zwracanej przy jednoczesnym ograniczeniu typów, które mogą być zwracane tylko do implementacji innego interfejsu.
Czy próbowałeś 'var returnList = nowa lista();' –
Tylko na uwadze, spójrz na swój TaskElement podczas wdrażania interfejsu, który musisz ustawić jako publiczny (domyślnie C# ustawia go jako prywatny) – ams4fy
Nic wspólnego z twoim pytaniem, ale jeśli dopiero zaczynasz C# powinieneś przeczytać [konwencje kodowania] (https://msdn.microsoft.com/en-gb/library/ff926074.aspx) inni gracze będą wdzięczni ty! – Jamiec