web-dev-qa-db-ja.com

ダイナミックには、プロジェクト参照からのプロパティの定義が含まれていません

次のようなエラーが表示されます。

「オブジェクト」には「タイトル」の定義が含まれていません

すべてのコードも github にあります

このようなConsoleApplication1があります

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Movie m = new Movie();
            var o = new { Title = "Ghostbusters", Rating = "PG" };
            Console.WriteLine(m.PrintMovie(o));
        }
    }
} 

およびMovie.cs

public class Movie : DynamicObject
{
    public string PrintMovie(dynamic o)
    {
        return string.Format("Title={0} Rating={1}", o.Title, o.Rating);
    }
} 

sAMEプロジェクトでは問題なく動作しますが、ConsoleApplication1を参照してConsoleApplication2を追加し、まったく同じコードを追加すると

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Movie m = new Movie();
            var o = new { Title = "Ghostbusters", Rating = "PG" };
            Console.WriteLine(m.PrintMovie(o));
        }
    }
}

エラーが発生します:

「オブジェクト」には「タイトル」の定義が含まれていません**

動的オブジェクト内にある場合でも。

  • o.Title 'o.Title'は、タイプ 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' dynamic {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException}の例外をスローしました

これがスクリーンショットです。 enter image description here

私はこのようなことをしていて、テストプロジェクトからムービー関数を呼び出そうとしています。

78
eiu165

ExpandoObjectを使用する必要があります

 dynamic o = new ExpandoObject();
 o.Title = "Ghostbusters";
 o.Rating = "PG";

 Console.WriteLine(m.PrintMovie(o));
73
JamahalSOF

Jahamalの答えはとは言いません(なぜエラーが表示されます)。その理由は、匿名クラスがアセンブリに対してinternalだからです。キーワードdynamicでは、メンバーの可視性をバイパスできません。

解決策は、匿名クラスを名前付きパブリッククラスに置き換えることです。

理由と 別の可能な解決策 を説明する別の良い例です。

data2.Personの呼び出しが失敗する理由は、data2の型情報が実行時に利用できないためです。使用できない理由は、匿名型がパブリックではないためです。メソッドがその匿名型のインスタンスを返すとき、それは匿名型のインスタンスを参照するSystem.Objectを返しています-情報のある型はメインプログラムで利用できません。動的ランタイムは、オブジェクトのPersonというプロパティを見つけようとしますが、所有している型情報からは解決できません。そのため、例外をスローします。 Personはパブリッククラスであるため、data.Nameへの呼び出しは正常に機能します。その情報は利用可能であり、簡単に解決できます。

これは、次のいずれかの場合に影響します(それ以上ではない場合)。

  1. System.Objectを使用して、非パブリック、非内部型を返しています。
  2. パブリックベース型を介して非パブリック、非内部派生型を返し、ベース型にない派生型のプロパティにアクセスしています。
  3. 別のアセンブリから匿名型にラップされたものを返しています。
121
Robert Važan

私の場合、Visual Studioで作成した単体テストプロジェクトと、データレイヤーライブラリでメソッドをテストする必要がある多くのケースがありました。すべてを変更したくはなかったので、次を使用してテストアセンブリを友人としてマークしました。

[アセンブリ:InternalsVisibleTo( "MyDataLayerAssemblyName")]

そしてそれはそれを解決しました。

例:

using System.Runtime.CompilerServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[Assembly: InternalsVisibleTo( "MyDataLayerAssembly" )]
namespace MyUnitTestProject.DataTests
{

   [TestClass]
   public class ContactTests
   {
      ...

参照: InternalsVisibleToAttribute Class

フレンドアセンブリ

23
Jelgab