Es ist tatsächlich möglich, einen anonymen Typ von einer Methode in einem bestimmten Anwendungsfall zurückzugeben. Werfen wir einen Blick!
Mit C # 7 ist es möglich, anonyme Typen von einer Methode zurückzugeben, obwohl dies mit einer geringfügigen Einschränkung verbunden ist. Wir werden eine neue Sprachfunktion namens lokale Funktion zusammen mit einem Indirektionstrick verwenden (eine andere Indirektionsebene kann jede Programmieraufgabe lösen, oder?).
Hier ist ein Anwendungsfall, den ich kürzlich identifiziert habe. Ich möchte alle Konfigurationswerte protokollieren, nachdem ich sie von geladen habe AppSettings
. Warum? Weil es eine Logik für fehlende Werte gibt, die auf Standardwerte zurückgesetzt werden, einige Parsing und so weiter. Eine einfache Möglichkeit, die Werte nach dem Anwenden der Logik zu protokollieren, besteht darin, sie alle in eine Klasse einzuteilen und in eine Protokolldatei zu serialisieren (mithilfe von log4net). Ich möchte auch die komplexe Logik des Umgangs mit Einstellungen zusammenfassen und diese von allem trennen, was ich damit tun muss. Alles ohne eine benannte Klasse zu erstellen, die nur für einen einzigen Gebrauch existiert!
Mal sehen, wie man dies mit einer lokalen Funktion löst, die einen anonymen Typ erstellt.
public static HttpClient CreateHttpClient()
{
// I deal with configuration values in this slightly convoluted way.
// The benefit is encapsulation of logic and we do not need to
// create a class, as we can use an anonymous class.
// The result resembles an expression statement that
// returns a value (similar to expressions in F#)
var config = Invoke(() =>
{
// slightly complex logic with default value
// in case of missing configuration value
// (this is what I want to encapsulate)
int? acquireTokenTimeoutSeconds = null;
if (int.TryParse(ConfigurationManager.AppSettings["AcquireTokenTimeoutSeconds"], out int i))
{
acquireTokenTimeoutSeconds = i;
}
// more complex logic surrounding configuration values ...
// construct the aggregate configuration class as an anonymous type!
var c = new
{
AcquireTokenTimeoutSeconds =
acquireTokenTimeoutSeconds ?? DefaultAcquireTokenTimeoutSeconds,
// ... more properties
};
// log the whole object for monitoring purposes
// (this is also a reason I want encapsulation)
Log.InfoFormat("Config={0}", c);
return c;
});
// use this configuration in any way necessary...
// the rest of the method concerns only the factory,
// i.e. creating the HttpClient with whatever configuration
// in my case this:
return new HttpClient(...);
// local function that enables the above expression
T Invoke<T>(Func<T> func) => func.Invoke();
}
Es ist mir gelungen, eine anonyme Klasse zu erstellen, und ich habe auch die Logik des Umgangs mit der Verwaltung komplexer Einstellungen in CreateHttpClient
und innerhalb ihres eigenen "Ausdrucks" zusammengefasst. Dies ist möglicherweise nicht genau das, was das OP wollte, aber es ist ein leichtgewichtiger Ansatz mit anonymen Typen, der derzeit in modernem C # möglich ist.