I had to solve a similar problem recently where none of the proposed solutions was satisfactory; constraining the type parameter was not practical. Instead, I let the consumers of the method decide how to munge the data. For example, you can write a generic version of String.Split() that returns a strongly typed List, so long as you tell it how to convert substrings into T's.
Once you are willing to shift responsibility up the call stack (and get comfortable passing lambdas around), you can generalize this pattern arbitrarily. For instance, if the way you GetData() varies (as some responses apparently assume), you can hoist that function into the caller's scope as well.
Demo:
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);
}
Functional programming gurus will probably yawn at this exploration: "you're just composing Map a few times." Even C++ guys might claim it's an example where template techniques (i.e. STL transform() + functors) require less work than generics. But as someone who primarily does C# it was nice to find a solution that preserved both type safety and idiomatic language usage.