Reputation: 1357
Full disclosure, I do not fully understand generics but am hoping the answer to this question will clear things up.
I have an application that allows a user to build a query of their own. The query will leverage the Entity Framework. I would like to return a list of the results whose type is dependent upon what column they queried. In other words i need a method that could have multiple return types. I derive the type using reflection on the column and then would like to pass to this method.
public static T getValues<T>(string ColName, Type type)
{
var result = db.AC_PROPERTY.Select(ColName);
if (type == typeof(string))
{
List<string> list = new List<string>();
//Query and add results to list.
return list;
}
if (type == typeof(double?) || type == typeof(double))
{
List<double> list = new List<double>();
//Query and add results to list.
return list;
}
if (type == typeof(int) || type == typeof(int?))
{
List<int> list = new List<int>();
//Query and add results to list.
return list;
}
if (type == typeof(DateTime))
{
List<DateTime> list = new List<DateTime>();
//Query and add results to list.
return list;
}
}
I am getting an error stating that I cannot implicitly convert List (or the respective type) to T.
Can someone explain this and perhaps walk me through how to accomplish this.
Upvotes: 1
Views: 573
Reputation: 13783
Ask yourself this: How are T
and Type type
meaningfully different? Why do you need both?
You don't.
Furthermore, while it's technically possible to check for a generic parameter's type, you should not be doing this. It's a code smell. If your method is generic, the method body should be generic as well. This includes not needing to know the exact value of T.
1. Get rid of Type type
public static List<T> getValues<T>(string ColName)
{
//...
}
Notice how this method would be used:
List<DateTime> myDateList = getValues<DateTime>("MyDateTimeColumn");
2. Make the method body generic
public static List<T> getValues<T>(string ColName)
{
List<T> myReturnList = new List<T>();
var selectedColumnValues = db.AC_PROPERTY.Select(ColName);
//Query and add results to list.
return myReturnList;
}
Looks a lot neater, doesn't it? I noticed you omitted the actual creating of the list; so I omitted it too for now.
I could get into the rest of the method body based on some assumptions, but there's a much more relevant consideration here.
Your method seems to be no different from LINQ's Select() method!
So instead of doing this with your custom built getValues<T>
method:
List<DateTime> myDateList = getValues<DateTime>("MyDateTimeColumn");
You can use the existing LINQ method:
List<DateTime> myDateList = myDataList.Select(item => item.MyDateTimeProperty).ToList();
(Note: ToList()
can be optional but is advisable due to lazy evaluation).
Upvotes: 5