次のようなエラーが表示されます。
「オブジェクト」には「タイトル」の定義が含まれていません
すべてのコードも 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));
}
}
}
エラーが発生します:
「オブジェクト」には「タイトル」の定義が含まれていません**
動的オブジェクト内にある場合でも。
これがスクリーンショットです。
私はこのようなことをしていて、テストプロジェクトからムービー関数を呼び出そうとしています。
ExpandoObjectを使用する必要があります
dynamic o = new ExpandoObject();
o.Title = "Ghostbusters";
o.Rating = "PG";
Console.WriteLine(m.PrintMovie(o));
Jahamalの答えはとは言いません(なぜエラーが表示されます)。その理由は、匿名クラスがアセンブリに対してinternal
だからです。キーワードdynamic
では、メンバーの可視性をバイパスできません。
解決策は、匿名クラスを名前付きパブリッククラスに置き換えることです。
理由と 別の可能な解決策 を説明する別の良い例です。
data2.Person
の呼び出しが失敗する理由は、data2
の型情報が実行時に利用できないためです。使用できない理由は、匿名型がパブリックではないためです。メソッドがその匿名型のインスタンスを返すとき、それは匿名型のインスタンスを参照するSystem.Objec
tを返しています-情報のある型はメインプログラムで利用できません。動的ランタイムは、オブジェクトのPerson
というプロパティを見つけようとしますが、所有している型情報からは解決できません。そのため、例外をスローします。Person
はパブリッククラスであるため、data.Name
への呼び出しは正常に機能します。その情報は利用可能であり、簡単に解決できます。これは、次のいずれかの場合に影響します(それ以上ではない場合)。
System.Object
を使用して、非パブリック、非内部型を返しています。- パブリックベース型を介して非パブリック、非内部派生型を返し、ベース型にない派生型のプロパティにアクセスしています。
- 別のアセンブリから匿名型にラップされたものを返しています。
私の場合、Visual Studioで作成した単体テストプロジェクトと、データレイヤーライブラリでメソッドをテストする必要がある多くのケースがありました。すべてを変更したくはなかったので、次を使用してテストアセンブリを友人としてマークしました。
[アセンブリ:InternalsVisibleTo( "MyDataLayerAssemblyName")]
そしてそれはそれを解決しました。
例:
using System.Runtime.CompilerServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[Assembly: InternalsVisibleTo( "MyDataLayerAssembly" )]
namespace MyUnitTestProject.DataTests
{
[TestClass]
public class ContactTests
{
...