2010-01-02 26 views
27

En varias tablas de bases de datos, tengo una propiedad y una columna de valores. Estoy usando Linq para SQL para acceder a la base de datos.¿Por qué obtengo el "error: ... debe ser un tipo de referencia" en mi método genérico C#?

Estoy escribiendo un método que devuelve un diccionario que contiene las propiedades/valores recuperados de la tabla de base de datos dada:

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; 
} 

Al compilar, me sale:

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>'

He intentado buscando este mensaje de error sin suerte.

Buscando en StackOverflow, esta pregunta parece similar, aunque con respecto a un parámetro List: Generic List<T> as parameter on method - aunque el parámetro todavía no es un tipo de referencia en las respuestas a esa pregunta, tampoco.

Lectura de la Guía de programación de C# en MSDN: http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx veo sus ejemplos, todos los que pasan los parámetros por referencia. Sin embargo, no puedo ver cómo pasar por referencia en mi caso particular, ya que el tipo genérico es solo para especificar el tipo genérico de tabla.

Cualquier puntero sería muy apreciado.

PS: appologies si se necesita tiempo para mí aceptar una respuesta, ya que esta función no está accesible (que estoy ciego y el uso de un lector de pantalla).

+0

Qué línea es que el mensaje de error en contra? – sblom

+4

@Mahesh: ¿Has leído la última línea de su publicación? @Saqib: es posible que desee enviar una nota a la gente de StackOverflow sobre eso. Estoy seguro de que querrán saber que una característica crítica de su sitio está rota y no funciona para un segmento significativo de sus visitantes. –

+1

Lo siento mal, no lo hice. Gracias por señalar. Disculpas –

Respuesta

59

Esto sucede debido a cómo se declara Table<T>:

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

El compilador se queja porque su método no tiene limitaciones en T, lo que significa que usted podría aceptar una T que no se ajusta a la especificación de Table<T>.

Por lo tanto, su método debe ser al menos tan estricto sobre lo que acepta. Prueba este lugar:

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

Simplemente añadir la restricción where T : class a su declaración de método.

Esto es necesario porque Table<TEntity> tiene una restricción where TEntity : class. De lo contrario, se podría llamar a su método genérico con un parámetro de tipo de estructura, que requeriría que CLR instanciara Table<TEntity> con ese parámetro de tipo de estructura, lo que violaría la restricción en Table<TEntity>.

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