值类型作为具有接口约束的泛型参数传递时是否被装箱?(作为我回答这个问题的研究结果,我(我想我有!)确定答案是“否”。但是,我必须在几个不同的地方找到答案才能弄清楚,所以我想如果社区投票关闭,我仍然有机会,我不会感到沮丧。)例如:voidf(Tval)whereT:IComparable{val.CompareTo(null);}voidg(){f(4);}4盒装?我知道将值类型显式转换为其实现的接口会触发装箱:((IComparable)4).CompareTo(null);//Int32“4”被装箱我不知道将值类型转换为具有为接口约束传递通用参数等于执行转换-语言“T是IComparable”类型建议转换,但是仅仅将T转换为IComparable似乎违背了泛型的全部目的!为了澄清,我想确保上面的代码中没有发生这些事情:当g调用f(4)时,由于f的参数类型上的IComparable约束,4是IComparable到IComparable。假设(1)没有发生,在f内部,val.CompareTo(null)不会将val从Int32转换为IComparable以调用CompareTo。但我想了解一下大概情况;不仅仅是int和IComparable的情况。现在,如果我将以下代码放入LinqPad:voidMain(){((IComparable)4).CompareTo(null);f(4);}voidf(Tval)whereT:IComparable{val.CompareTo(null);然后查看生成的IL:IL_0001:ldc.i4.4IL_0002:boxSystem.Int32IL_0007:ldnullIL_0008:callvirtSystem.IComparable.CompareToIL_000D:popIL_000E:ldarg.0IL_000F:ldc.i4.4IL_0010:callUserQuery.ff:IL_0000:nopIL_0001:ldarga.s01IL_0003:ldnullIL_0004:约束。0100001BIL_000A:callvirtSystem.IComparable.CompareToIL_000F:popIL_0010:ret预期的显式转换发生在阵容中,但f本身*或主调用站点中没有明显的装箱。这是个好消息。然而,这只是一种类型的一个例子。所有情况都可以假设这种缺乏拳击的东西吗?*这篇MSDN文章讨论了受约束的前缀和状态,只要被调用的方法是在类型本身(而不是基类)上实现的,将callvirt与callvirt一起使用将不会触发值类型的装箱。我不确定的是当我们到达这里时类型是否仍然是值类型。正如您已经知道的那样,当一个结构被传递给一个泛型方法时,它并没有被装箱。运行时为每个“类型参数”创建新方法。当您调用具有值类型的泛型方法时,您实际上是在调用为??每个值类型创建的专用方法。所以不需要拳击。装箱发生在调用未直接在结构类型中实现的接口方法时。规范在这里调用它:如果thisType是一个值类型并且thisType没有实现方法,ptr被取消引用、装箱,并作为“this”指针传递给callvirt方法指令。最后一种情况只有在方法定义在Object、ValueType或Enum上并且未被thisType覆盖时才会发生。在这种情况下,装箱会生成原始对象的副本。然而,由于Object、ValueType和Enum的方法都没有修改对象的状态,因此无法检测到这一事实。因此,只要您显式[1]在结构本身中实现接口成员,就不会发生装箱。泛型方法具体如何、何时、何地?1.不要与显式接口实现相混淆。这意味着您的接口方法应该在结构本身而不是其基类型中实现。一个简单的测试是简单地创建一个带有可以更改它的接口方法的可变结构。从泛型方法调用该接口方法并查看原始结构是否已发生变化。公共接口IMutable{voidMutate();int值{得到;}}publicstructEvil:IMutable{publicintvalue;publicvoidMutate(){值=9;}publicintValue{get{返回值;}}}publicstaticvoidFoo(Tmutable)whereT:IMutable{mutable.Mutate();Console.WriteLine(mutable.Value);}staticvoidMain(string[]args2){Evilevil=newEvil(){value=2};Foo(邪恶);在这里我们看到9被打印出来,这意味着实际变量是变异的,而不是副本,所以结构没有装箱。以上是C#学习教程:作为带有接口约束的泛型参数传递时,值类型是否被装箱?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
