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

时间:2022-10-06 16:53:59

I am getting an error that says:

我得到的错误是:

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

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

all the code is also on github

所有的代码都在github上。

I have a ConsoleApplication1 that looks like this

我有一个像这样的应用程序

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

and Movie.cs

和Movie.cs

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

it works fine from the SAME project, but if I add ConsoleApplication2 with a reference to ConsoleApplication1 and add the Exact same code

它可以在同一个项目中正常工作,但是如果我添加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));
        }
    }
}

I get an error:

我得到一个错误:

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

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

even though it is in the dynamic object.

即使它在动态对象中。

  • o.Title 'o.Title' threw an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' dynamic {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException}
  • o。标题“o。标题“抛出类型的异常”Microsoft.CSharp.RuntimeBinder。RuntimeBinderException“动态{ Microsoft.CSharp.RuntimeBinder.RuntimeBinderException }

Here is a screen shot: dynamic并不包含来自项目引用的属性的定义

这是一个屏幕截图:

I am doing something like this and trying to call the movie function from a test project.

我正在做这样的事情,并试图从一个测试项目中调用movie函数。

3 个解决方案

#1


64  

You need to use an ExpandoObject

您需要使用ExpandoObject

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

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

#2


97  

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.

Jahamal的回答并没有说你为什么会犯错误。原因是匿名类是程序集内部的。关键字动态不允许您绕过成员可见性。

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 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.

调用data2的原因。Person failed是data2的类型信息在运行时不可用。它不可用的原因是匿名类型不是公共的。当方法返回该匿名类型的实例时,它将返回一个系统。对象,该对象引用匿名类型的实例——主程序不能使用该匿名类型的信息。动态运行时试图查找对象上名为Person的属性,但无法从其具有的类型信息解析它。因此,它抛出一个异常。调用数据。由于Person是公共类,所以名称可以很好地工作,因此可以很容易地解析信息。

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. 您使用System.Object返回非公开的非内部类型。
  3. 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.
  4. 通过公共基类型返回非公共的、非内部的派生类型,并访问派生类型中不属于基类型的属性。
  5. You're returning anything wrapped inside an anonymous type from a different assembly.
  6. 您将返回来自不同程序集的匿名类型中包含的任何内容。

#3


18  

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:

在我的例子中,我有一个在Visual Studio上创建的单元测试项目,在很多情况下,我需要在数据层库上测试方法。我不想把所有的都更改,所以我将测试程序集标记为朋友,使用:

[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]

[组装: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: InternalsVisibleToAttribute Class

引用:InternalsVisibleToAttribute类

Friend Assemblies

朋友集会

#1


64  

You need to use an ExpandoObject

您需要使用ExpandoObject

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

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

#2


97  

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.

Jahamal的回答并没有说你为什么会犯错误。原因是匿名类是程序集内部的。关键字动态不允许您绕过成员可见性。

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 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.

调用data2的原因。Person failed是data2的类型信息在运行时不可用。它不可用的原因是匿名类型不是公共的。当方法返回该匿名类型的实例时,它将返回一个系统。对象,该对象引用匿名类型的实例——主程序不能使用该匿名类型的信息。动态运行时试图查找对象上名为Person的属性,但无法从其具有的类型信息解析它。因此,它抛出一个异常。调用数据。由于Person是公共类,所以名称可以很好地工作,因此可以很容易地解析信息。

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. 您使用System.Object返回非公开的非内部类型。
  3. 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.
  4. 通过公共基类型返回非公共的、非内部的派生类型,并访问派生类型中不属于基类型的属性。
  5. You're returning anything wrapped inside an anonymous type from a different assembly.
  6. 您将返回来自不同程序集的匿名类型中包含的任何内容。

#3


18  

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:

在我的例子中,我有一个在Visual Studio上创建的单元测试项目,在很多情况下,我需要在数据层库上测试方法。我不想把所有的都更改,所以我将测试程序集标记为朋友,使用:

[assembly:InternalsVisibleTo("MyDataLayerAssemblyName")]

[组装: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: InternalsVisibleToAttribute Class

引用:InternalsVisibleToAttribute类

Friend Assemblies

朋友集会