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

电影.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));
        }
    }
}

我收到一个错误:

“对象”不包含“标题”的定义**

即使它在动态对象中。

  • o.Title 'o.Title' 抛出类型为 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' 动态 {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 测试项目。

其中“内容”是一个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 回答