2010-01-02 3 views
27

Dans diverses tables de base de données, j'ai à la fois une propriété et une colonne de valeur. J'utilise Linq to SQL pour accéder à la base de données.Pourquoi est-ce que j'obtiens "erreur: ... doit être un type de référence" dans ma méthode générique C#?

J'écris une méthode qui retourne un dictionnaire contenant les propriétés/valeurs extraites de la table de base de données spécifique:

private static Dictionary<string, string> GetProperties<T>(Table<T> table) 
{ 
    Dictionary<string, string> properties = new Dictionary<string, string>(); 

    foreach (var row in table) 
    { 
     properties[row.Property]=row.Value; 
    } 

    return properties; 
} 

Lors de la compilation, je reçois:

Error 1 The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'System.Data.Linq.Table<TEntity>'

J'ai essayé la recherche de ce message d'erreur sans chance.

Recherche StackOverflow, cette question semble similaire, mais en ce qui concerne un paramètre Liste: Generic List<T> as parameter on method - si le paramètre est toujours pas un type de référence dans les réponses à cette question, que ce soit.

La lecture du C# Guide de programmation sur MSDN: http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx Je vois leurs exemples passent tous les paramètres par référence. Cependant, je ne vois pas comment passer par référence dans mon cas particulier, puisque le type générique est juste pour spécifier le type générique de Table.

Tous les pointeurs seraient très appréciés.

PS: appologies s'il me faut du temps pour d'accepter une réponse, car cette fonctionnalité est actuellement pas accessible (je suis aveugle et utilise un lecteur d'écran).

+0

Quelle ligne est ce message d'erreur contre? – sblom

+4

@Mahesh: Avez-vous lu la dernière ligne de son message? @Saqib: Vous pourriez vouloir envoyer une note aux gens de StackOverflow à ce sujet. Je suis sûr qu'ils voudront savoir qu'une fonctionnalité critique de leur site est cassée et ne fonctionne pas pour un segment important de leurs visiteurs. –

+1

Désolé ma mauvaise, je n'ai pas. Merci de m'avoir signalé. Excuses –

Répondre

59

Cela se produit à cause de la façon dont Table<T> est déclaré:

public sealed class Table<TEntity> : IQueryable<TEntity>, 
    IQueryProvider, IEnumerable<TEntity>, ITable, IQueryable, IEnumerable, 
    IListSource 
where TEntity : class // <-- T must be a reference type! 

Le compilateur se plaint parce que votre méthode n'a pas de contraintes sur T, ce qui signifie que vous pouvez accepter un T qui ne sont pas conformes à la spécification Table<T>.

Ainsi, votre méthode doit être au moins aussi strictes sur ce qu'il accepte. Essayez ceci:

private static Dictionary<string, string> GetProperties<T>(Table<T> table) where T : class 
21

il suffit d'ajouter la contrainte where T : class à votre déclaration de méthode.

Cela est nécessaire car Table<TEntity> a une contrainte where TEntity : class. Sinon, votre méthode générique pourrait être appelée avec un paramètre de type struct, ce qui nécessiterait le CLR instancier Table<TEntity> avec ce paramètre de type struct, ce qui serait contraire à la contrainte sur Table<TEntity>.

0
public class TEntityRepository<TEntity> : EFRepository<TEntity> , ITEntityRepository<TEntity> 
    where TEntity : class, new() 
{ 
} 
Questions connexes