2012-02-23 20 views
59

我得到一個錯誤,指出:動態不包含從項目引用的一個屬性的定義

'object' does not contain a definition for 'Title'

所有的代碼還對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); 
    } 
} 

它工作正常,從相同的項目,但如果我添加ConsoleApplication2一起ConsoleApplication1參考,並添加完全相同的代碼

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)); 
     } 
    } 
} 

我得到一個錯誤:

'object' does not contain a definition for 'Title'**

即使它在動態的對象中。

  • o.Title 'o.Title' 投擲類型的異常 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' 動態{Microsoft.CSharp.RuntimeBinder.RuntimeBinderException}

這裏是一個屏幕截圖: enter image description here

我正在做這樣的事情,並試圖從測試項目調用電影功能。

+1

可能重複://計算器.com/questions/2630370/c-sharp-dynamic-can not-access-properties-from-anonymous-types-declared-in-anot) – 2012-02-23 16:22:41

回答

61

您需要使用ExpandoObject

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

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

他經歷了很多麻煩,寫了一個詳細的問題如果讓他知道他爲什麼會出錯,就像Robert建議的那樣 – 2014-09-19 08:45:20

+0

似乎你可以在expando對象中使用內聯初始值設定程序功能嗎? – 2015-01-06 16:31:06

+0

棒極了,它也適用於單元測試 – 2016-07-24 11:08:53

90

Jahamal的答案不說爲什麼你的錯誤。原因是程序集的匿名類是internal。關鍵字dynamic不允許您繞過會員可見度。

解決方法是用named public class替換匿名類。

這是另一個很好的例子,解釋原因和another possible solution

The reason the call to data2.Person fails is that the type information of data2 is not available at runtime. The reason it's not available is because anonymous types are not public. When the method is returning an instance of that anonymous type, it's returning a System.Objec t which references an instance of an anonymous type - a type who's info isn't available to the main program. The dynamic runtime tries to find a property called Person on the object, but can't resolve it from the type information it has. As such, it throws an exception. The call to data.Name works fine since Person is a public class, that information is available and can be easily resolved.

This can affect you in any of the following cases (if not more):

  1. You're returning a non-public, non-internal type using System.Object .
  2. You're returning a non-public, non-internal derived type via a public base type and accessing a property in the derived type that's not in the base type.
  3. You're returning anything wrapped inside an anonymous type from a different assembly.
+0

您能否在您的答案中引用您的來源? – d3dave 2015-06-25 07:07:58

+0

@ d3dave可以測試答案中的兩個索賠。類可見性可以在.NET反編譯器中檢查。可以在具有不同可見度的成員的測試課上檢查'dynamic'的訪問規則。 – 2015-06-25 16:31:48

+1

這是OP爲什麼做的問題的真正答案。 – 2017-05-08 10:47:54

15

在我來說,我有我的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

Friend Assemblies

(HTTP [C# '動態' 不能訪問由在另一組件中聲明匿名類型性質]的
+1

原因是Alexander Stepaniuk所說的。您的評論是解決方案。謝謝! – 2015-05-12 18:22:04

+0

我不能讓這個在netcoreapp1.1項目之間工作,不知道這是我做錯了什麼。 – 2017-11-01 18:28:30

相關問題