14

以下に示すように、使用できる CSharp 式評価器に取り組んでいます。このコンポーネントは、コードを生成してメモリにコンパイルした後、生成されたアセンブリを読み込み、生成されたクラスのインスタンスを作成して実行します。結果は辞書に保存されます。

私の問題は、例外で失敗するコードの最後の行まで、すべて正常に実行されることです。

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 'object' には 'FirstName' の定義が含まれていません。

ただし、Visual Studio はプロフェッショナルな変数コンテンツを表示できます。

Professional = { FirstName = Juan Pablo, 
                LastName = Ibañez, 
                Certifications = <>f__AnonymousType0`3[System.String,System.String,System.String][], 
                SayHi = System.Action }

そして、これはコードです:

    static void Main(string[] args)
    {
        const string data = @"results[""professional""] = 
        new
        {
            FirstName = ""Juan Pablo"",
            LastName = ""Ibañez"",
            Certifications = new[]
            {
                new { Provider=""MSFT"", ExamCode = ""70-536"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" },
                new { Provider=""MSFT"", ExamCode = ""70-505"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" },
                new { Provider=""MSFT"", ExamCode = ""70-563"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" }
            },

            SayHi = new System.Action(()=> System.Console.WriteLine(""Hi""))
        };";

        var eval = CSharpEvaluator.Evaluate(data); // return a disctionary<string, object>
        dynamic professional = eval["professional"];
        Console.WriteLine("First Name: {0}", professional.FirstName);

何か案は?

ありがとうございました。

4

1 に答える 1

27

編集:私はそれを持っていると思います。匿名型は内部的なものであるため、型はdynamicバインダーには見えません。現在確認中...

うん、それだけです。正確なエラー メッセージに注意してください。'object' does not contain a definition for 'FirstName'".

使用しているのは、それが実際にオブジェクトを独自のアセンブリ内から参照objectできる唯一の型であるためです。これは、アセンブリが動的に読み込まれることとは関係ありません。別のアセンブリにあるだけです。

編集: [InternalsVisibleTo]「公開」アセンブリにそれを適用させることができれば、属性を使用してこれを回避できます。次に例を示します。

// In Library.dll
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("Test")]

public class Library
{
    public static object Foo()
    {
        return new { ID = 1 };
    }
}

// In Test.exe
using System;

class Test
{
    static void Main()
    {
        dynamic d = Library.Foo();
        Console.WriteLine(d.ID);
    }
}

属性をコメントアウトすると、質問に従って Test.exe が壊れます。属性を使用すると、正常に機能します。C# コンパイラの作成者はすべてを考えています :)

于 2011-02-21T15:26:17.613 に答える