Tuve que resolver un problema similar recientemente donde ninguna de las soluciones propuestas fue satisfactoria; restringir el parámetro de tipo no era práctico. En su lugar, I permite a los consumidores del método decidir cómo administrar los datos. Por ejemplo, puede escribir una versión genérica de String.Split() que devuelva una lista fuertemente tipada, siempre y cuando le diga cómo convertir subcadenas en T.
Una vez que esté dispuesto a pasar la responsabilidad por la pila de llamadas (y sentirse cómodo pasando las lambdas), puede generalizar este patrón arbitrariamente. Por ejemplo, si la forma en que GetData() varía (como aparentemente asumen algunas respuestas), también puede elevar esa función al alcance de la persona que llama.
Demostración:
static void Main(string[] args)
{
var parseMe = "Hello world! 1, 2, 3, DEADBEEF";
// Don't need to write a fully generic Process() method just to parse strings -- you could
// combine the Split & Convert into one method and eliminate 2/3 of the type parameters
List<string> sentences = parseMe.Split('!', str => str);
List<int> numbers = sentences[1].Split(',', str => Int32.Parse(str, NumberStyles.AllowHexSpecifier | NumberStyles.AllowLeadingWhite));
// Something a little more interesting
var lettersPerSentence = Process(sentences,
sList => from s in sList select s.ToCharArray(),
chars => chars.Count(c => Char.IsLetter(c)));
}
static List<T> Split<T>(this string str, char separator, Func<string, T> Convert)
{
return Process(str, s => s.Split(separator), Convert).ToList();
}
static IEnumerable<TOutput> Process<TInput, TData, TOutput>(TInput input, Func<TInput, IEnumerable<TData>> GetData, Func<TData, TOutput> Convert)
{
return from datum in GetData(input)
select Convert(datum);
}
gurús de programación funcional probablemente bostezo en esta exploración: "que sólo estás componiendo un mapa un par de veces" Incluso los chicos de C++ podrían afirmar que es un ejemplo en el que las técnicas de plantilla (es decir, STL transform() + functors) requieren menos trabajo que los genéricos. Pero como alguien que principalmente hace C#, fue agradable encontrar una solución que preservara tanto la seguridad del tipo como el uso del lenguaje idiomático.
De acuerdo que ese debería ser el objetivo final, pero realmente no lo ayuda a resolver el problema inmediato. –