Parece que la respuesta es "no".
Cuando se llama a Transform
directamente, tiene que especificar un parámetro de tipo:
int i = Transform<int>("");
Así que, hipotéticamente, si se puede pasar una función genérica construida de forma incompleta como desea, que había necesidad de especificar el los parámetros de tipo así:
void GeneralizedFunction(string aStringA, string aStringB, Func<string, T> aAction)
{
A result1 = aAction<A>(aStringA);
B result2 = aAction<B>(aStringB);
// Do something with A and B here
}
Por lo tanto, me parece que usted podría hacer hipotéticamente esto, si C# tenía una sintaxis de esa manera.
¿Pero cuál es el caso de uso? Además de transformar las cadenas en el valor predeterminado de un tipo arbitrario, no veo mucho uso para esto. ¿Cómo podría definir una función que proporcionaría un resultado significativo en cualquiera de dos tipos diferentes utilizando la misma serie de enunciados?
EDITAR
Un análisis de por qué no es posible:
Cuando se utiliza una expresión lambda en su código, que se compila en cualquiera de un delegado o un árbol de expresión; en este caso, es un delegado. No puede tener una instancia de tipo genérico "abierto"; en otras palabras, para crear un objeto a partir de un tipo genérico, se deben especificar todos los parámetros de tipo.En otras palabras, no hay forma de tener una instancia de un delegado sin proporcionar argumentos para todos sus parámetros de tipo.
Una de las características útiles del compilador de C es las conversiones de grupos de métodos implícitos, donde el nombre de un método (un "grupo de métodos") se puede convertir implícitamente a un tipo de delegado que representa una de las sobrecargas de ese método. Del mismo modo, el compilador convierte implícitamente una expresión lambda a un tipo de delegado. En ambos casos, el compilador emite código para crear una instancia del tipo de delegado (en este caso, pasarlo a la función). Pero la instancia de ese tipo de delegado aún necesita tener un argumento de tipo para cada uno de sus parámetros de tipo.
Dar la función genérica como función genérica, al parecer, el compilador tendría que ser capaz de pasar el grupo método o la expresión lambda al método sin conversión, por lo que el aAction
parámetro de alguna manera tendría un tipo de "grupo de métodos" o "expresión lambda". Entonces, la conversión implícita a un tipo de delegado podría ocurrir en los sitios de llamadas A result1 = aAction<A>(aStringA);
y B result2 = aAction<B>(aStringB);
. Por supuesto, en este punto, nos adentramos en el universo de contrafactuales e hipotéticos.
La solución que se me ocurrió durante el almuerzo era esto, asumiendo una función Deserialize<T>
que toma una cadena que contiene datos serializados y devuelve un objeto de tipo T
:
void GeneralizedFunction<T>(string aStringA, string aStringB, Func<T, string> stringGetter)
{
A result1 = Deserialize<A>(stringGetter(aStringA));
B result2 = Deserialize<B>(stringGetter(aStringB));
}
void Example(string serializedA, string serializedB, string pathToA, string pathToB, FileInfo a, FileInfo b)
{
GeneralizedFunction(serializedA, serializedB, s => s);
GeneralizedFunction(pathToA, pathToB, File.ReadAllText);
GeneralizedFunction(a, b, fi => File.ReadAllText(fi.FullName));
}
¿Qué es lo quieres hacer exactamente? ya que no desea darle a GeneralizedFunction ningún tipo de información sobre la función Transformar, ¿por qué no acepta un func nuevamente tomando una cadena y devolviendo un objeto (del que todos saben que todo el mundo está *) – Polity
El asunto es que su "Haga algo con Los marcadores de posición A y B ocultan la parte problemática. ¿Serán A y B siempre tipos particulares? Entonces no necesitas genéricos. ¿Son tipos arbitrarios (quizás con restricciones)? Entonces 'GeneralizedFunction' necesita ser genérico en ellos. – AakashM
A y B son tipos concretos, pero Transform es una función genérica. – Max