104

次のようなエラーが発生します。

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

すべてのコードは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);
    }
} 

同じプロジェクトからは正常に機能しますが、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}の例外をスローしました。

スクリーンショットは次のとおりです。ここに画像の説明を入力してください

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

4

5 に答える 5

161

Jahamalの答えは、なぜエラーが発生するのかを示していません。その理由は、匿名クラスがinternalアセンブリに対するものであるためです。キーワードdynamicでは、メンバーの可視性をバイパスできません。

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

これは、理由と考えられる解決策を説明する別の良い例です。

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

これは、次のいずれかの場合に影響を与える可能性があります(それ以上ではない場合)。

  1. を使用して、非公開、非内部型を返しますSystem.Object。2.パブリックベースタイプを介して非パブリック、非内部派生タイプを返し、ベースタイプにない派生タイプのプロパティにアクセスします。3.別のアセンブリから匿名タイプにラップされたものを返します。
于 2014-03-20T18:55:36.677 に答える
91

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

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

 Console.WriteLine(m.PrintMovie(o));
于 2012-02-23T16:40:50.163 に答える
33

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

[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]

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

例:

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

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

   [TestClass]
   public class ContactTests
   {
      ...

参照:

于 2015-04-16T19:46:19.727 に答える
3

私の場合、xUnitテストプロジェクトがあります。

ここで、「content」はjson文字列です。

このコードはエラーをスローします:

dynamic parsed = JsonConvert.DeserializeObject<dynamic>(content);

このコードは機能します。次のように動的なExpandoObjectを使用します

dynamic parsed = JsonConvert.DeserializeObject<ExpandoObject>(content);
于 2019-10-16T18:28:42.597 に答える
0

私はパーティーにかなり遅れていますが、これが私がやった方法です。

dynamic myObject = GetSomeObject();

//check if myObject is a special Object
(if myObject is specialObject)
{
    string specialPropery = ((specialObject))myObject).SpecialProperty;
    Console.WriteLine("The object is a special type. SpecialPropery: {specialPropery }");
}
else
{
    Console.WriteLine("The object normal type.");
}
于 2021-04-29T14:49:48.277 に答える