0

非常に基本的な質問です。次の方法を検討してください。

public object Foo(object bar) {... }

public dynamic Bar(dynamic bar) {... }

実際には、このようなメソッド シグネチャはありませんが、この例では簡潔にするために単純化して、メソッド パラメーターの「dynamic vs object」キーワードと return の 2 つのことを示しています。

これら 2 つの方法の違いは何ですか? 同じ IL またはパフォーマンスへの影響を生成しますか?

参照/ワークスルー/例に基づいて、ダイナミックが追加されたダイナミック機能を備えたオブジェクトのようであることを伝えると、どちらも同じものであると思いますが、戻り値に別のダイナミック プロパティ/メソッドを追加する場合のように、使用法に基づいてのみ異なります。しかし、考慮すべき別の重要な点があるかどうかはまだ疑問です。

上記のようなメソッドを持つクラスがあり、Bar以下のようなメソッド シグネチャを持つインターフェイスを実装している場合 (またはその逆)、コンパイラは何も文句を言わないことに注意してください。

object Bar(object bar);

約 3 年の存在の後、Web API によって消費される動的リポジトリを作成し、(動的) JSON を生成するなど、プロジェクトで動的機能を使用する機会があります。

public interface IRepository
{
    IEnumerable GetAll(string entityName, int skip, int take);
    int Count(string entityName);
    dynamic GetById(string entityName, int key);
    void Add(string entityName, dynamic entity);
    void Remove(string entityName, int key);
}

エンティティが具体的ではなくentityName、db 列で定義されている場合。IEnumerableまたはのいずれかを使用することも検討していますIEnumerable<dynamic>。何か考えはありますか?

4

2 に答える 2

2

それらによっては、{... }確かに同じILにはなりません! 検討:

public object Foo(object bar)
{
  Use(bar);
}

void Use(int i)
{
}
void Use(string s)
{
}
void Use(IConvertible c)
{
}
void Use<T>(IEnumerable<T> e)
{
}
void Use(object o)
{
}

IL には、 の最後のオーバーロードへの呼び出しが含まれているだけですUse

しかし、dynamic bar代わりにパラメーターが as として宣言されていた場合、IL には非常に複雑なオーバーロード解決アルゴリズムを起動するコードが含まれます。これにより、いずれかのオーバーロードが呼び出されたり、エラーが発生したりする可能性があります (たとえばbar==null、最適なオーバーロードを決定できません)。

明らかに非常に異なるILです。アプリケーションの実行時にバインドdynamic全体を実行する必要がある場合 ( )、プログラムのコンパイル時に一度だけ実行するのではなく、明らかにパフォーマンスが低下します。

この場合の遅くて複雑なコードは、dynamic常に同じオーバーロードを呼び出すのではなく、私たちが本当に望んでいたものである可能性があることも明らかです。

于 2013-07-27T15:15:13.273 に答える
0

dynamicin C# はobjectIL に変換されます。

.method private hidebysig instance object Foo(object bar) cil managed
{...}

.method private hidebysig instance object Bar(object bar) cil managed
{
  .param [0]
  .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
  .param [1]
  .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
  ...
}

署名は同じままでDynamic、戻り値と最初のパラメーターに属性のみが追加されます。

他のコードを変更せずにパラメーターの型を からdynamicに変更できる場合は、それを行います。object

于 2015-04-02T21:36:42.960 に答える