Sembra che la risposta sia "no".
Quando si chiama Transform
direttamente, è necessario specificare un parametro di tipo:
int i = Transform<int>("");
Quindi ipoteticamente, se si poteva passare una funzione generica incompleto-costruito come si vuole, avresti bisogno di specificare il parametri di tipo così:
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
}
Quindi mi sembra che si potrebbe ipoteticamente fare questo, se C# ha avuto una sintassi del genere.
Ma qual è il caso d'uso? A parte trasformare le stringhe al valore predefinito di un tipo arbitrario, non vedo molto l'uso per questo. Come potresti definire una funzione che fornisca un risultato significativo in uno dei due diversi tipi utilizzando la stessa serie di affermazioni?
EDIT
L'analisi del motivo per cui non è possibile:
Quando si utilizza un'espressione lambda nel codice, viene compilato in sia un delegato o di un albero di espressione; in questo caso, è un delegato. Non puoi avere un'istanza di tipo generico "aperto"; in altre parole, per creare un oggetto da un tipo generico, è necessario specificare tutti i parametri del tipo.In altre parole, non c'è modo di avere un'istanza di un delegato senza fornire argomenti per tutti i suoi parametri di tipo.
Una delle funzioni utili del compilatore C# è rappresentata dalle conversioni di gruppi di metodi impliciti, in cui il nome di un metodo (un "gruppo di metodi") può essere convertito implicitamente in un tipo delegato che rappresenta uno degli overload di tale metodo. Allo stesso modo, il compilatore converte implicitamente un'espressione lambda in un tipo delegato. In entrambi i casi, il compilatore emette il codice per creare un'istanza del tipo delegato (in questo caso, per passarlo alla funzione). Ma l'istanza di quel tipo delegato deve ancora avere un argomento di tipo per ciascuno dei suoi parametri di tipo.
per passare la funzione generica come funzione generica, sembra, il compilatore avrebbe bisogno di essere in grado di passare gruppo metodo o l'espressione lambda al metodo senza conversione, così il aAction
parametro avrebbe in qualche modo un tipo di "metodo gruppo" o "espressione lambda". Quindi, la conversione implicita a un tipo di delegato potrebbe avvenire nei siti di chiamata A result1 = aAction<A>(aStringA);
e B result2 = aAction<B>(aStringB);
. Naturalmente, a questo punto, siamo ben lungi dall'universo dei contrafactuals e degli ipotetici.
La soluzione mi è venuta durante il pranzo è stato questo, assumendo una funzione Deserialize<T>
che prende una stringa contenente dati serializzati e restituisce un oggetto di 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));
}
cosa si tratta vuoi fare esattamente? dal momento che non vuoi dare a GeneralizedFunction alcun tipo di informazione riguardante la funzione Transform, perché non accettare una funzione di nuovo prendendo una stringa e restituendo un oggetto (di cui tutti sanno che tutti sono *) – Polity
Il fatto è, il tuo "Fai qualcosa con Il segnaposto A e B "nasconde la parte problematica. A e B saranno sempre tipi particolari? Quindi non hai bisogno di farmaci generici. Sono tipi arbitrari (magari con vincoli)? Quindi 'GeneralizedFunction' deve essere generico in loro. – AakashM
A e B sono tipi concreti, ma Trasforma è una funzione generica. – Max