1

C#4.0ダイナミックのエキスパートについて説明してください。

オブジェクトを作成する前に構成するのに役立つ流暢なビルダークラスがあります。このインターフェイスには、メソッドSetParameters(...)があります。

    public FluentBuilder<TInterface> SetParameters(dynamic parameters)
    {
        _parameters = parameters;
        return this;
    }

私は流暢なインターフェースを消費するためにこれを行っています:

var order = new Order();

/* Setting up parameters */
dynamic parameters = new ExpandoObject();
parameters.Transaction = transactionObj;
parameters.CurrentPrincipal = Thread.CurrentPrincipal;

var proxiedOrder = ObjectProxyFactory
    .Configure<IOrder>(order)
    .FilterMethods(o => o.InsertOrder())
    .AddPreDecoration(AppConcerns.JoinSqlTransaction)
    .AddPreDecoration(AppConcerns.EnterLog)
    .AddPostDecoration(AppConcerns.ExitLog)
    .AddPostDecoration(AppConcerns.SecurityCheck)
    .SetParameters(parameters)
    .Teste() //this method doesn't exist in the fluent builder
    .CreateProxy();

var result = proxiedOrder.InsertOrder();

上記のスニペットでコメントされているように、Teste()というメソッドはFluentインターフェイスに存在しませんが、Intelissenseは、動的を返すようにSetParametersを呼び出した後、任意のメソッドを記述できますが、コードでわかるように、SetParametersは動的ではないFluentInterfaceを返します。

上記のコードは、実行時にTeste()メソッドがFluentBuilderクラスに見つからないため、実行時に失敗します。

設計時にこの問題を解決し、正しいIntelissenseを取得するには、パラメーターをExpandoObjectクラスにキャストする必要があります。

var proxiedOrder = ObjectProxyFactory
.Configure<IOrder>(order)
.FilterMethods(o => o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters((ExpandoObject)parameters) //cast to ExpandoObject
.Teste() //now intelissense is giving me an "red" error and solution will not compile
.CreateProxy();

var result = proxiedOrder.InsertOrder();

メソッドチェーンでC#動的パラメーターを渡すと、そのメソッドが動的パラメーターを受け取った後、メソッドの戻りタイプがC#動的オブジェクトを返さない場合でも、メソッドへの後続の呼び出しはC#動的オブジェクトを返すように動作することがわかりました。動的。

バグですか?それとも、これは起こると予想されますか?

4

1 に答える 1

6

それが起こると予想されます。動的引数を含むメソッド呼び出しは動的に解決されます。正確なオーバーロードは実行時まで決定できないため、コンパイル時に戻り型が不明であるため、として扱われdynamicます。場合によっては、C#コンパイラはより多くの情報を推測できますが(静的メソッド呼び出しの場合など)、簡単にするために推測しません。動的な値を含む変数のいくつかの式のみが非動的な型を持っています。(メモリからは、is演算子は常にboolであり、コンストラクターは常に構築中の型を返すと想定されます。)

編集:私はついにスペックリファレンスを見つけました。セクション7.6.5から:

次の少なくとも1つが当てはまる場合、呼び出し式は動的にバインドされます(§7.2.2)。

  • プライマリ式のコンパイル時の型は動的です。
  • オプションのargument-listの少なくとも1つの引数には、コンパイル時の型が動的であり、primary-expressionにはデリゲート型がありません。

この場合、コンパイラはinvocation-expressionをdynamic型の値として分類します。

于 2012-06-03T16:07:53.167 に答える