Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get "error: ... must be a reference type" in my C# generic method?

Tags:

c#

linq-to-sql

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).

like image 750
Saqib Avatar asked Jan 02 '10 18:01

Saqib


2 Answers

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 
like image 96
John Feminella Avatar answered Oct 01 '22 07:10

John Feminella


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

like image 35
itowlson Avatar answered Oct 01 '22 07:10

itowlson