29

In various database tables I have both a property and a value column. I'm using Linq to SQL to access the database.

I'm writing a method which returns a dictionary containing the properties/values retrieved from the given database table:

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

Upon compiling, I get:

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

I've tried searching for this error message without luck.

Searching StackOverflow, this question seems similar, though regarding a parameter List: Generic List<T> as parameter on method - though the parameter still isn't a reference type in the answers to that question, either.

Reading the C# Programming Guide on MSDN: http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx I see their examples all pass the parameters by reference. However, I can't see how to pass by reference in my particular case, since the generic type is just for specifying the generic type of Table.

Any pointers would be much appreciated.

PS: Appologies if it takes time for me to accept an answer, as this feature is currently not accessible (I'm blind and use a screen reader).

Community
  • 1
  • 1
Saqib
  • 7,242
  • 7
  • 41
  • 55
  • Which line is that error message against? – sblom Jan 02 '10 at 18:56
  • 4
    @Mahesh: Did you read the last line of his post? @Saqib: You might want to fire a note to the StackOverflow folks about that. I'm sure they'll want to know that a critical feature of their site is broken and doesn't work for a significant segment of their visitors. – John Feminella Jan 02 '10 at 19:01
  • 1
    Sorry my bad, I didn't. Thanks for pointing out. Apologies – Mahesh Velaga Jan 02 '10 at 19:24

3 Answers3

64

This happens because of how Table<T> is declared:

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

The compiler is complaining because your method has no constraints on T, which means that you could accept a T which doesn't conform to the specification of Table<T>.

Thus, your method needs to be at least as strict about what it accepts. Try this instead:

private static Dictionary<string, string> GetProperties<T>(Table<T> table) where T : class
John Feminella
  • 303,634
  • 46
  • 339
  • 357
22

Just add the constraint where T : class to your method declaration.

This is required because Table<TEntity> has a where TEntity : class constraint. Otherwise your generic method could be called with a struct type parameter, which would require the CLR to instantiate Table<TEntity> with that struct type parameter, which would violate the constraint on Table<TEntity>.

itowlson
  • 73,686
  • 17
  • 161
  • 157
0
public class TEntityRepository<TEntity> : EFRepository<TEntity> , ITEntityRepository<TEntity>
    where TEntity : class, new()
{
}