Musiałem rozwiązać podobny problem ostatnio, gdy żadne z proponowanych rozwiązań nie było zadowalające; ograniczenie parametru typu nie było praktyczne. Zamiast tego, I pozwól konsumentom metody zdecydować, jak usunąć dane. Na przykład możesz napisać ogólną wersję String.Split(), która zwraca listę mocno napisaną, o ile powiesz mu, jak konwertować podciągów na T.
Gdy chcesz przenieść odpowiedzialność za stos wywoławczy (i poczuć się komfortowo, przechodząc wokół niego), możesz uogólnić ten schemat dowolnie. Na przykład, jeśli sposób, w jaki GetData() jest różny (jak niektórzy najwyraźniej przypuszczają), możesz również wciągnąć tę funkcję do zakresu dzwoniącego.
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);
}
funkcjonalne guru programowania będzie prawdopodobnie ziewając przy tym: „eksploracji. Jesteś po prostu komponowania mapie kilka razy” Nawet użytkownicy C++ mogą twierdzić, że jest to przykład, w którym techniki szablonowe (tj. Transformacja STL() + funktory) wymagają mniej pracy niż generyczne. Ale jako ktoś, kto przede wszystkim robi C#, było miło znaleźć rozwiązanie, które zachowało zarówno bezpieczeństwo typu i użycie idiomatycznego języka.
Uzgodniono, że powinien to być ostateczny cel, ale tak naprawdę nie pomoże mu rozwiązać natychmiastowego problemu. –