【问题标题】:Compiler says dynamic property is missing but I can see it编译器说缺少动态属性,但我可以看到
【发布时间】:2015-08-01 15:47:48
【问题描述】:

我开始潜入C# Dynamics and Metaprogramming 的世界,遇到了一些麻烦。

我设法创建了一个CodeDom 树,并生成了以下代码:

namespace Mimsy {
    using System;
    using System.Text;
    using System.Collections;

    internal class JubJub {
         private int _wabeCount;
         private ArrayList _updates;

         public JubJub(int wabeCount) {
               this._updates = new ArrayList();
               this.WabeCount = wabeCount;
         }

         public int WabeCount {
               get {
                   return this._wabeCount;
               }
               set {
                   if((value < 0))
                        this._wabeCount = 0;
                   else
                        this._wabeCount = value;
                   this._updates.Add(this._wabeCount);
               }
         }

         public string GetWabeCountHistory() {
               StringBuilder result = new StringBuilder();
               int ndx;
               for(ndx = 0; (ndx < this._updates.Count); ndx = ndx + 1) {
                     if((ndx == 0))
                            result.AppendFormat("{0}", this._updates[ndx]);
                     else
                            result.AppendFormat(", {0}", this._updates[ndx]);
               }
         }
    }
}

然后,我将此命名空间动态编译为名为 "dummy" 的程序集。

我可以成功得到这个类型的一个实例:

string typeName = "Mimsy.JubJub";
Type type = dummyAssembly.GetType(typeName);
dynamic obj = Activator.CreateInstance(type, new object[] { 8 });
//obj is a valid instance type

如果我调试这段代码,我可以在调试器中看到obj 实际上具有属性WabeCount

但是,当试图访问这个属性时,编译器会喊出动态属性不存在。

【问题讨论】:

  • wabes[ndx]的类型是什么?他们是int吗?
  • 它们实际上是 int 包装为 object 的值
  • 尝试将它们投射到(int),例如obj.WabeCount = (int)wabes[ndx]
  • @xanatos 我尝试投射它们,但问题仍然存在
  • 不要在课堂上使用internaldynamic 可能不喜欢!使用public。然后进行选角...(所以试试public classobj.WabeCount = (int)wabes[ndx])(见stackoverflow.com/a/18806787/613130

标签: c# .net dynamic reflection metaprogramming


【解决方案1】:

您的代码存在一个或两个问题:

  • 您正在使用internal class,并尝试使用dynamic 访问它。这两件事不能很好地结合在一起。见https://stackoverflow.com/a/18806787/613130。使用public clasas

  • 您需要先转换该值,然后再将其分配给wabeCount,例如:

    obj.WabeCount = (int)wabes[ndx]
    

请注意,从技术上讲,如果您的“主”程序集是强命名的,您可以将 InternalsVisibleToAttribute 添加到“动态”程序集以使其 internal“事物”对主程序集可见......我确实认为这将是浪费工作。

【讨论】:

  • 我不认为这是 dynamic 的问题 - 您根本无法从另一个程序集访问 internal 方法
  • @PanagiotisKanavos 如果您使用反射,您可以。所以你的句子不是“绝对真理”。简单地说,dynamic 使用“标准”.NET 解析规则(没有私有访问,没有内部程序集等等)。这不是立即直观的。情况可能恰恰相反。 (发现的时候我很惊讶,因为dynamic内部使用反射来发现东西,所以它使用反射似乎有点奇怪但是没有反射强大)
  • 我们谈论的是dynamic,而不是反射。您还可以使用反射访问私有字段。 dynamic 虽然不是反射,但“错误”并不是真正的错误。这就是为什么它被关闭为“按设计”
  • @PanagiotisKanavos 我还没有谈到“错误”。这是一个奇怪的特征。它肯定有它的道理(甚至不用阅读你没有链接的页面我就可以想象:dynamic“用户”不需要ReflectionPermission,因为他们只能使用“公共”的东西。如果dynamic允许访问private/protected/internal,“用户”需要ReflectionPermission
猜你喜欢
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 2011-07-26
  • 2011-03-15
  • 1970-01-01
相关资源
最近更新 更多