C# 动态不包含来自项目引用的属性定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9416095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
dynamic does not contain a definition for a property from a project reference
提问by eiu165
I am getting an error that says:
我收到一条错误消息:
'object' does not contain a definition for 'Title'
“对象”不包含“标题”的定义
all the code is also on github
所有代码也在github上
I have a ConsoleApplication1 that looks like this
我有一个像这样的 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));
}
}
}
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
它在 SAME 项目中工作正常,但是如果我添加 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'**
“对象”不包含“标题”的定义**
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.Title 'o.Title' 抛出了类型为 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' 动态 {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException} 的异常
Here is a screen shot: 
这是一个屏幕截图: 
I am doing something like this and trying to call the movie function from a test project.
我正在做这样的事情,并试图从测试项目中调用电影功能。
采纳答案by JamahalSOF
You need to use an ExpandoObject
您需要使用 ExpandoObject
dynamic o = new ExpandoObject();
o.Title = "Ghostbusters";
o.Rating = "PG";
Console.WriteLine(m.PrintMovie(o));
回答by Robert Va?an
Jahamal's answer doesn't say whyyou get the error. The reason is that the anonymous class is internalto the assembly. Keyword dynamicdoesn't allow you to bypass member visibility.
Jahamal 的回答并没有说明为什么会出现错误。原因是匿名类是internal给程序集的。关键字dynamic不允许您绕过成员可见性。
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.Personfails is that the type information ofdata2is 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 aSystem.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 calledPersonon the object, but can't resolve it from the type information it has. As such, it throws an exception. The call todata.Nameworks fine sincePersonis 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):
- You're returning a non-public, non-internal type using
System.Object.- 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.
- You're returning anything wrapped inside an anonymous type from a different assembly.
调用
data2.Person失败的原因是 的类型信息data2在运行时不可用。它不可用的原因是匿名类型不是公开的。当该方法返回该匿名类型的实例时,它会返回一个System.Objec引用匿名类型实例的 t - 主程序无法使用其信息的类型。动态运行时尝试查找Person对对象调用的属性,但无法根据其拥有的类型信息解析它。因此,它会引发异常。调用data.Name工作正常,因为它Person是一个公共类,该信息可用并且可以轻松解决。在以下任何一种情况下(如果不是更多),这可能会影响您:
- 您正在使用 返回非公共、非内部类型
System.Object。- 您通过公共基类型返回非公共、非内部派生类型,并访问派生类型中不在基类型中的属性。
- 您正在从不同的程序集中返回包裹在匿名类型中的任何内容。
回答by Jelgab
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")]
[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:
参考:
回答by Guilherme Ferreira
In my case I have a xUnit test project.
就我而言,我有一个 xUnit 测试项目。
Where 'content' is a json string.
其中 'content' 是一个json 字符串。
This code throws error:
此代码引发错误:
dynamic parsed = JsonConvert.DeserializeObject<dynamic>(content);
This code works. Use ExpandoObjectinsted of dynamic like this:
此代码有效。像这样使用动态的ExpandoObject插入:
dynamic parsed = JsonConvert.DeserializeObject<ExpandoObject>(content);

