実際には、特定のユースケースでメソッドから匿名型を返すことができます。みてみましょう!
C# 7 では、わずかな制約はありますが、メソッドから匿名型を返すことができます。ローカル関数と呼ばれる新しい言語機能を、間接的なトリックと一緒に使用します (間接的な別のレイヤーでプログラミングの課題を解決できますよね?)。
これは私が最近特定したユースケースです。からロードした後、すべての構成値をログに記録したいと考えていますAppSettings
。なんで?デフォルト値に戻る欠落した値に関するいくつかのロジック、いくつかの解析などがあるためです。ロジックを適用した後に値をログに記録する簡単な方法は、それらをすべてクラスに入れ、ログファイルにシリアル化することです (log4net を使用)。また、設定を処理するための複雑なロジックをカプセル化し、それらを処理する必要があるものから分離したいと考えています。一度だけ使用するために存在する名前付きクラスを作成する必要はありません。
匿名型を作成するローカル関数を使用してこれを解決する方法を見てみましょう。
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();
}
匿名クラスの構築に成功し、複雑な設定管理を処理するロジックをすべてCreateHttpClient
独自の「式」内にカプセル化しました。これは、OP が望んでいたものとはまったく異なる場合がありますが、現在の C# で現在可能な匿名型を使用した軽量なアプローチです。