Dynamic 不包含来自项目引用的属性的定义

我收到一个错误,它说:

“ object”不包含“ Title”的定义

所有代码都在 Github

我有一个控制台应用程序看起来像这样

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

电影

public class Movie : DynamicObject
{
public string PrintMovie(dynamic o)
{
return string.Format("Title={0} Rating={1}", o.Title, o.Rating);
}
}

它在同一个项目中工作得很好,但是如果我在添加 Console Application2时引用 Console Application1并添加完全相同的代码

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”抛出一个类型为“ Microsoft.CSharp. RuntimeBinder. RuntimeBinderException”的异常动态{ Microsoft.CSharp. RuntimeBinder. RuntimeBinderException }

下面是一个截图:enter image description here

我正在做类似的事情,并尝试从一个测试项目中调用 film 函数。

61126 次浏览

You need to use an ExpandoObject

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


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

Jahamal's answer doesn't say why you get the error. The reason is that the anonymous class is internal to the assembly. Keyword dynamic doesn't allow you to bypass member visibility.

The solution is to replace the anonymous class with named public class.

Here's another good example explaining the reason and 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.Object which references an instance of an anonymous type - a type whose 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.

In my case I had a Unit Test project that I created on Visual Studio and a lot of cases where I needed to test methods on a data layer library. I didn't want to change all of them so I marked the test assembly as a friend by using:

[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]

And that solved it.

Example:

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


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


[TestClass]
public class ContactTests
{
...

References:

In my case I have a xUnit test project.

Where 'content' is a json string.

This code throws error:

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

This code works. Use ExpandoObject insted of dynamic like this:

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

I am way late to the party, but here is a way I did it.

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