dynamic不包含项目引用中属性的定义

时间:2012-02-23 15:32:49

标签: c# .net dynamic dynamicobject

我收到的错误是:

  

'object'不包含'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);
    }
} 

它可以在SAME项目中正常工作,但如果我添加ConsoleApplication2并引用ConsoleApplication1并添加Exact相同的代码

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'不包含'Title'的定义**

即使它在动态对象中。

  • o.Title'o.Title'抛出了类型'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'dynamic {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException}
  • 的异常

以下是屏幕截图:enter image description here

我正在做这样的事情并试图从测试项目调用电影功能。

5 个答案:

答案 0 :(得分:113)

Jahamal的回答并没有说为什么你得到错误。原因是匿名类是程序集internal。关键字dynamic不允许您绕过会员可见性。

解决方案是用命名的public class替换匿名类。

这是解释原因和another possible solution的另一个好例子。

  

调用data2.Person失败的原因是data2的类型信息在运行时不可用。它不可用的原因是因为匿名类型不公开。当该方法返回该匿名类型的实例时,它返回一个System.Objec t,它引用一个匿名类型的实例 - 一个类型的信息不可用于主程序。动态运行时尝试在对象上查找名为Person的属性,但无法从其拥有的类型信息中解析它。因此,它会引发异常。对data.Name的调用工作正常,因为Person是一个公共类,该信息可用并且可以轻松解决。

     

在以下任何情况下(如果不是更多),这会对您产生影响:

     
      
  1. 您使用System.Object返回非公开的非内部类型。
  2.   
  3. 您将通过公共基类型返回非公共的非内部派生类型,并访问不在基类型中的派生类型的属性。
  4.   
  5. 您将从不同的程序集中返回包含在匿名类型中的任何内容。
  6.   

答案 1 :(得分:72)

您需要使用ExpandoObject

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

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

答案 2 :(得分:21)

在我的情况下,我有一个我在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

答案 3 :(得分:0)

就我而言,我有一个xUnit测试项目。

其中“内容”是 json字符串

此代码引发错误:

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

此代码有效。像这样使用动态的 ExpandoObject

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

答案 4 :(得分: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.");
}