Sto scrivendo due metodi di estensione. Uno per lavorare su un singolo oggetto, e un altro per lavorare su una collezione di oggetti. Quando si chiama il metodo di estensione, il compilatore C# sembra confondersi su quale utilizzare e fallisce la compilazione.Compilazione del metodo di estensione C#/verifica della compatibilità non riuscita in base all'ordine dei namespace
Più sorprendentemente, se sposto i metodi di estensione in spazi dei nomi diversi, anche se includo entrambi gli spazi dei nomi nel callsite, la compilazione fallisce solo se gli spazi dei nomi sono in ordine alfabetico in ordine particolare - la modifica degli spazi dei nomi causa la compilazione.
Ecco il codice:
public static class DBObjectExtensions
{
public static void PopulateRelations<T>(this T obj, params RelationToPrefetch[] relationsToPrefetch) where T : IDBObject
{
if (obj == null)
{
return;
}
obj.Transaction.PopulateRelations<T>(new[]{ obj }, relationsToPrefetch);
}
public static void PopulateRelations<T>(this IEnumerable<T> objects, params RelationToPrefetch[] relationsToPrefetch) where T : IDBObject
{
var first = objects.FirstOrDefault();
if (first == null)
{
return;
}
first.Transaction.PopulateRelations<T>(objects, relationsToPrefetch);
}
}
Questa è la linea callsite che non riesce la compilazione:
List<ITable> list = ... // ITable inherits from IDBObject
list.PopulateRelations(xxx);
Fails con CS0311 errore:
tipo 'System.Collections. Generic.List 'non può essere utilizzato come parametro di tipo' T 'nel tipo generico o nel metodo' Granta.MI.DBObjectExtensions.PopulateRelations (T, params Granta.MI. RelationToPrefetch [])'. Non esiste alcuna conversione implicita del riferimento da "System.Collections.Generic.List" a "Granta.MI.IDBObject".
Si noti che questa riga ha esito positivo la compilazione se si elimina il 2 ° metodo di estensione.
Si noti inoltre che la scrittura di metodi trampolino (per ogni possibile tipo di raccolta ...) funziona anche:
public static void PopulateRelations<T>(this List<T> objects, params RelationToPrefetch[] relationsToPrefetch) where T : IDBObject
{
((IEnumerable<T>)objects).PopulateRelations(relationsToPrefetch);
}
public static void PopulateRelations<T>(this IList<T> objects, params RelationToPrefetch[] relationsToPrefetch) where T : IDBObject
{
((IEnumerable<T>)objects).PopulateRelations(relationsToPrefetch);
}
Perché non è possibile la figura del compilatore che c'è un metodo di estensione di corrispondenza? E più confusamente, se metto uno dei metodi in uno spazio dei nomi diverso e includo quello spazio dei nomi, perché la compilazione ha avuto successo? C'è qualcosa che posso fare per risolvere questo problema?
La risoluzione del sovraccarico non tiene conto dei vincoli. Inoltre, non sembra che sia necessario 'T' nella funzione del metodo, perché è necessario usare' T' per il proprio interno invece di usare 'IDbObject'? – Jcl
@Jcl le persone si confondono molto spesso con l'uso di 'T', come hai detto se non hai bisogno di' T' all'interno del metodo di estensione semplicemente cambia i metodi come nella risposta @ jakub-lortz. – mijail
Scuse - Non ho incluso il motivo per non farlo nella mia risposta.Il motivo è che 'Transaction.PopulateRelations' accetta anche un tipo T e poi chiama' typeof' quindi ho bisogno che T sia un tipo concreto non solo 'IDBObject'. –