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


91

私は言うエラーが出ます:

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

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

これがスクリーンショットです: ここに画像の説明を入力してください

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


回答:


79

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

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

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

28
彼は複雑な質問を書くために多くの困難を経験しました、ロバートが示唆するように、彼にエラーが発生している理由を彼に知らせておくといいでしょう
Luis Ferrao 14

2
インライン初期化機能をexpandoオブジェクトで使用できないようですか?
Roberto Bonini、2015年

1
ExpandoObjectはどこで使用すべきですか?動的オブジェクトの作成または動的オブジェクトの解析
Hosein Aqajani 2017

ロバートの答えは役に立ったので、もっと情報を探す必要がありましたが、より深い理解が必要でした。Oreillyは、動的な型に関する良い記事をここに掲載しました:oreilly.com/learning/building-c-objects-dynamically
Billy Willoughby

137

ジャハマルの答えは、なぜエラーが出るのを述べていません。その理由は、匿名クラスはinternalアセンブリに対するものだからです。キーワードでdynamicは、メンバーの表示をバイパスすることはできません。

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

理由と考えられる別の解決策を説明する別の良い例を次に示します

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

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

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

1
回答で出典を引用していただけませんか。
d3dave 2015年

@ d3dave回答の2つの主張をテストできます。クラスの可視性は.NETデコンパイラーで確認できます。のアクセスルールはdynamic、さまざまな可視性のメンバーを持つテストクラスでチェックできます。
RobertVažan15年

3
これが、OPが行っていたことが問題である理由に対する真の答えです。
Matti Virkkunen

1
どちらもnetcoreapp1.1であるソースプロジェクトとテストプロジェクトの間でこれを機能させることができません。それが私のせいなのか、これが.NET Coreで機能しないのですか?
Anthony Mastrean 2017年

27

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

[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]

そしてそれで解決しました。

例:

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

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

   [TestClass]
   public class ContactTests
   {
      ...

参照:


1
その理由は、アレクサンダー・ステパニウクが言ったことです。あなたのコメントが解決策です。ありがとう!
Pato Loco

これをnetcoreapp1.1プロジェクト間で機能させることはできません。これが間違って行っていることかどうかはわかりません。
Anthony Mastrean 2017年

ジェルガブさん、ありがとうございました!これで、ダイナミックをExpanoObjectに置き換える必要はありません。単体テストで依存関係注入を使用していますが、動的を使用できず、単体テストプロジェクトから機能させることができません。しかし、これで解決しました!
ShameWare

あなた(開発者)は、匿名タイプの作成元である反対のプロジェクト、またはその両方にこれを追加する必要があることに注意してください。
ryanwebjackson

0

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

ここで、「コンテンツ」はjson文字列です。

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

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

このコードは機能します。次のように動的に組み込まれた ExpandoObjectを使用します。

dynamic parsed = JsonConvert.DeserializeObject<ExpandoObject>(content);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.