11

プロジェクトで次のコードを検討してください。

static void Main(string[] args)
{
    DoSomething(new { Name = "Saeed" });
}

public static void DoSomething(dynamic parameters)
{
    Console.WriteLine(parameters.Name);
}

これは魅力のように機能します。ただし、これら 2 つの関数を 2 つの異なるプロジェクトに分けるとすぐに、コードが壊れます。

// This code is in a Console Application
static void Main(string[] args)
{
    ExternalClass.DoSomething(new { Name = "Saeed" });
}

// However, this code is in a Class Library; Another project
public class ExternalClass
{

    public static void DoSomething(dynamic parameters)
    {
        Console.WriteLine(parameters.Name);
    }
}

2番目のケースで発生するエラーは次のとおりです。

object' には 'Name' の定義が含まれていません (RuntimeBinderException)

なぜこのエラーが発生するのですか? 代替方法は何ですか?動的パラメータを別のライブラリのメソッドに渡し、そこで簡単な方法で使用するにはどうすればよいですか?

注: 私はよく知っているExpandoObjectので、使いたくありません。

4

1 に答える 1

8

あなたのコードは匿名型を使用しています。もともとは、C# バージョン 3 で追加された Linq selectクエリ式で役立つように意図されていました。 残念ながら、C# コンパイラは、匿名型のメンバーのアクセシビリティ修飾子をinternalに設定して生成します。アクセシビリティは、CLR によって適用されます。イテレータも同じアセンブリで生成されるため、Linq では問題になりません。dynamicキーワードでそれらを使用することは想定されていませんでした。これは、後の C# バージョンであるバージョン 4 で追加されました。

これは、コードがすべて同じアセンブリ内にある限り、正常に機能することを意味します。ただし、オブジェクトを別のアセンブリのコードに渡すとすぐに、内部によって適用される制限が開始され、ブームが発生します。

少し public クラスを宣言するだけで回避できます。ExpandoObject も機能しますが、不要なオーバーヘッドが追加されます。

于 2013-07-13T12:09:50.743 に答える