首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法将ref枚举转换为ref dynamic?

无法将ref枚举转换为ref dynamic?
EN

Stack Overflow用户
提问于 2013-03-23 08:54:19
回答 2查看 1.4K关注 0票数 3

给定一个函数声明

代码语言:javascript
复制
dynamic DoSomething(dynamic inputObject)

我可以使用枚举将其调用为inputObject

代码语言:javascript
复制
MyEnum myEnum;
myEnum = DoSomething(myEnum);

但是由于某种原因,如果函数将inputObject声明为ref dynamic类型而不是dynamic类型

代码语言:javascript
复制
dynamic DoSomething(ref dynamic inputObject)

以下内容由于无效转换而不起作用:

代码语言:javascript
复制
MyEnum myEnum;
DoSomething(ref myEnum);

枚举是否有什么特殊之处,使我无法在ref dynamic中使用它们

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-24 21:19:24

作为引用传递的唯一方法是将myEnum转换为动态类型,然后按引用传递它。我认为我们应该仔细研究一下生成的IL,以了解幕后发生了什么。让我们找出原因并分析这个程序:

代码语言:javascript
复制
 enum MyEnum{
     A,B
}

void Main()
{
    MyEnum  myEnum = MyEnum.B; //Assign a variable

    DoSomethingByEnum(myEnum); //Pass myEnum
    DoSomethingDynamicByValue(myEnum); //pass myEnum to a dynamic parameter

    dynamic dyn = myEnum;      //assign myenum to a dynamic variable
    DoSomethingDynamicByRef(ref dyn);    //pass it as a reference
}

MyEnum DoSomethingByEnum(MyEnum a)
{
   return a;
}

dynamic DoSomethingDynamicByValue(dynamic inputObject)
{
   return inputObject;

}

dynamic DoSomethingDynamicByRef(ref  dynamic inputObject)
{
  return inputObject;

} 

首先,我们调用DoSomethingByEnum,通过值传递变量myEnum,然后调用DoSomethingDynamicByValue,再次传递myEnum,但隐式地将其包装为动态类型。这是在MSIL级别上发生的事情:

代码语言:javascript
复制
Main:
  IL_0001:  ldc.i4.1    // MyEnum myEnum = MyEnum.B;
  IL_0002:  stloc.0     // myEnum popped from evaluation stack and stored in a local variable 
  IL_0003:  ldarg.0     
  IL_0004:  ldloc.0     // myEnum loaded from local variable at index 0 and passed to the function
  IL_0005:  call        DoSomethingByEnum
  IL_000A:  pop         
  IL_000B:  ldarg.0     
  IL_000C:  ldloc.0     // myEnum
  IL_000D:  box         MyEnum // dynamic dyn = myEnum;  
                       // myEnum Converted from value type to a true object reference of type dynamic
  IL_0012:  call        DoSomethingDynamicByValue

DoSomethingByEnum( myEnum )和DoSomethingDynamicByValue(动态)之间的唯一区别是对变量myEnum进行装箱(通过创建一个新对象并将数据从值类型复制到新分配的动态对象中来实现)。请查看此Box Opcode

让我们来看看DoSomethingByEnum(MyEnum)和DoSomethingDynamicByValue(动态) IL:

代码语言:javascript
复制
 DoSomethingDynamicByValue:
    IL_0000:  nop         
    IL_0001:  ldarg.1     
    IL_0002:  stloc.0      
    IL_0003:  br.s        IL_0005
    IL_0005:  ldloc.0      
    IL_0006:  ret         

DoSomethingByEnum:
    IL_0000:  nop         
    IL_0001:  ldarg.1     
    IL_0002:  stloc.0      
    IL_0003:  br.s        IL_0005
    IL_0005:  ldloc.0     
    IL_0006:  ret         

无论变量的类型如何,两个函数的IL代码都是完全相同的。我们甚至可以有一个随心所欲的对象类型,但是通过调用传递和共享变量的方式是不会改变的。

让我们来看看在DoSomethingDynamicByRef中发生了什么(动态引用)。

继续使用main方法

代码语言:javascript
复制
Main:
    IL_0018:  ldloc.0     // myEnum
    IL_0019:  box         UserQuery.MyEnum
    IL_001E:  stloc.1     // dyn
    IL_001F:  ldarg.0     
    IL_0020:  ldloca.s    01 // loads the address of dyn onto the stack
    IL_0022:  call        UserQuery.DoSomethingDynamicByRef

DoSomethingDynamicByRef:
   IL_0000:  nop         
   IL_0001:  ldarg.1     
   IL_0002:  ldind.ref   //
   IL_0003:  stloc.0     
   IL_0004:  br.s        IL_0006
   IL_0006:  ldloc.0      
   IL_0007:  ret

此IL与前两个示例之间的差异依赖于加载和获取地址的这两条指令:

代码语言:javascript
复制
   ldloca.s    01  // loads the address of dyn onto the stack

   ldind.ref       // Loads the object reference at address addr onto the stack as a type O

我认为不可能传递不同对象类型的地址的原因在上面的ldloca.sldind.ref的两个IL指令的MSDN页面中解释了

格式正确的微软中间语言(MSIL)确保以与指针类型一致的方式使用ldind指令。最初推送到堆栈上的地址必须与计算机上对象的自然大小对齐

希望这能澄清一点。

票数 3
EN

Stack Overflow用户

发布于 2013-03-24 21:22:37

dynamic在编译后实际上是object,所以你实际上是在问为什么你不能:

代码语言:javascript
复制
void DoSomething(ref object input);

MyEnum myEnum;
DoSomething(ref myEnum);

原因是,ref不能这样使用,请考虑下面的情况如何违反类型安全:

代码语言:javascript
复制
void DoSomething(ref object input) {
    input = new object();
}

因此,正如Eric在评论中提到的,Enum在这里并没有什么特别之处。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15582121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档