Me he encontrado con un pequeño problema, y no puedo encontrarlo.Sobrecargas de métodos que difieren solo por la restricción genérica
Quiero tener estos 3 sobrecargas:
public IList<T> GetList<T>(string query) where T: string
public IList<T> GetList<T>(string query) where T: SomeClass
public IList<T> GetList<T>(string query) where T: struct
Obviamente la primera restricción ni siquiera se compilará solo, por lo que es mi primer número. (Me doy cuenta que podría hacerlo IList pero quiero la misma sintaxis para los tres)
De todos modos, el motivo de todo esto es que estos métodos forman parte de un proceso de ejecución de consultas SQL en una base de datos. Quiero ser capaz de devolver el resultado como una lista de cadenas (en caso de que alguien seleccione una columna varchar), una lista de tipos de valores (int, float, lo que sea) o una lista de clases (estas clases representan tablas y contienen varias columnas)
Espero que la parte sea algo comprensible :-)
De todos modos, mi gran problema es obviamente que no puedo hacer estas sobrecargas, ya que usan el mismo nombre y lista de parámetros.
Tampoco puedo combinarlos en el mismo método, ya que necesito llamar a un método en SomeClass en esa implementación, así que a menos que quiera hacer una conversión de tipo pesado, o peor, reflexión, necesito esa restricción.
Me doy cuenta de que lo que estoy tratando de hacer no es posible, entonces lo que estoy buscando es un buen enfoque, que imitará mis intenciones.
Si algo de esto es un poco confuso, sienta libre de hacer :-)
Editar:
Aquí está mi código actual para el "donde T: SomeClass" versión. Estoy tratando de añadir soporte para cuerda/valuetypes a este código actual, por lo que tal vez mi enfoque inicial es simplemente mal - cualquier idea, básicamente, son bienvenidos :-)
public IList<TValue> GetList<TValue>(string query) where TValue : DbTable, new()
{
DataSet dataSet = GetDataSet(query);
IList<TValue> result = new List<TValue>();
if (dataSet.Tables.Count > 0)
{
foreach (DataRow row in dataSet.Tables[0].Rows)
{
TValue col = new TValue();
col.Fill(row);
result.Add(col);
}
}
return result;
}
Como se puede ver que necesitan el tipo exacto de DbTable para crear el constructor adecuado. El relleno es un método abstracto de DbTable (que es una clase abstracta).
Sí nombres diferentes es simple, sin embargo, quiero hacer que sea casi como si fuera un solo y el mismo método, que acepta estas limitaciones. Podría hacer una GetList sin restricción, y luego arrojar una excepción si el tipo es incorrecto; sin embargo, en el caso de SomeClass, en realidad son clases que heredan SomeClass, y necesito el tipo exacto, ya que las nuevo(). Espera un segundo y publicaré mi GetList existente donde T: SomeClass code. –
Steffen
En ese caso, puede desordenarse con 'MakeGenericMethod', etc .; no es una buena opción. –
Exactamente, y tiene razón en que un simple control de tipo para las cadenas y los tipos de valores no son problemáticos. Está sacando los tipos de niños de DbTable, estoy preocupado. – Steffen