问题标签 [boxing]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
6 回答
1529 浏览

c# - 我应该使用结构还是类?

我陷入了经典设计的困境。我正在编写一个包含值和测量单位元组(例如 7.0 毫米)的 C# 数据结构,我想知道是否应该使用引用类型或值类型。

结构的好处应该是更少的堆操作,让我在表达式中获得更好的性能,并减少垃圾收集器的压力。对于像这样的简单类型,这通常是我的选择,但在这种具体情况下存在缺点。

元组是相当通用的分析结果框架的一部分,其中结果在 WPF 应用程序中以不同的方式呈现,具体取决于结果值的类型。WPF 使用它的所有数据模板、值转换和模板选择器处理这种弱类型非常好。这意味着如果我的元组表示为结构,则该值将经历大量装箱/拆箱。事实上,元组在表达式中的使用对于装箱场景中的使用来说是次要的。为了避免所有的拳击,我考虑将我的类型声明为一个类。另一个对结构体的担忧是,WPF 中的双向绑定可能存在缺陷,因为在代码中的某处得到元组的副本而不是引用副本会更容易。

我也有一些方便的运算符重载。我可以使用重载的比较运算符将毫米与厘米进行比较,而不会出现问题。但是,如果我的元组是一个类,我不喜欢重载 == 和 != 的想法,因为约定是 == 和 != 是引用类型的 ReferenceEquals(与 System.String 不同,这是另一个经典讨论)。如果 == 和 != 被重载,有人会写if (myValue == null)并在有一天 myValue 为 null 时得到一个讨厌的运行时异常。

另一个方面是,在 C# 中(与例如 C++ 不同)没有明确的方法来区分代码使用中的引用类型和值类型,但语义却非常不同。我担心我的元组(如果声明为结构)的用户假定类型是一个类,因为大多数自定义数据结构都是并且假定引用语义。这是另一个论点,为什么人们应该更喜欢类,因为那是用户所期望的并且没有“。” /“->”来区分它们。一般来说,除非我的分析器告诉我使用结构,否则我几乎总是使用类,这仅仅是因为类语义最有可能被其他程序员所期望,而 C# 只是模糊地暗示它是一件事还是另一件事。

所以我的问题是:

在决定是否应该进行价值或参考时,我应该考虑哪些其他因素?

== / != 在任何情况下都可以证明类中的重载是合理的吗?

程序员假设东西。大多数人可能会认为所谓的“点”是一种值类型。如果您阅读一些带有“UnitValue”的代码,您会假设什么?

鉴于我的使用说明,您会选择什么?

0 投票
2 回答
417 浏览

.net - 将一个结构数组分配给另一个相同结构的数组

在 Vb.net 中,我试图将一个结构数组分配给另一个相同结构的数组

ifo 中的任何更改都会反映在 info2 中,此分配网络是由参考发生的。

我不希望信息的任何更改反映在 info2 中,反之亦然,在分配之后,我该如何实现?

0 投票
5 回答
4256 浏览

java - 扩展java整数缓存

有一个一般建议可以使用Integer.valueOf(int),而不是new Integer(int)因为缓存。

在 JDK 5+ 中,您应该真正使用valueOf,因为Integer现在可以在 和 之间缓存Integer对象,-128并且每次都127可以将相同的对象返回给您,Integer(0)而不是在全新的相同Integer对象上浪费对象构造。

怎样才能扩大范围?

0 投票
1 回答
23273 浏览

c# - 从字典中获取价值不开箱?

我想知道是否可以运行以下代码但没有拆箱行:-

或者,如果有另一种方法来做这种操作?

这是完整的代码:-

提前致谢!!

理查德。

0 投票
7 回答
11181 浏览

java - 拳击和加宽

这两者有什么区别。我知道拳击正在将原始值转换为参考。什么在扩大。另外应该先做拳击还是扩大应该做的顺序是什么?

0 投票
3 回答
907 浏览

c# - 如何在不使用编程语言的装箱支持的情况下“装箱”一个值?

我想在不使用任何 .NET 语言的内置支持的情况下对值进行装箱。

也就是说,给定一个枚举值,我想要一个表示该值及其类型的引用类型对象。

这是能够从后期绑定纯 C++ 代码中传递枚举值的子目标,这是一个可能的解决方案,因此,我不是在寻找如何使用例如 C# 装箱(这很容易,并且在很多方面都无关紧要)。

以下代码产生...

但是,使用更多记录的FieldInfo类,这是签名所MakeTypedReference要求的,我得到一个异常,说参数不是RuntimeFieldInfo.

不成功的代码,实验性的,C#:

有助于使上述代码“工作”的答案会非常好。

指出另一种实现拳击的方法的答案(也许以上完全和完全错误? - 这只是实验性的)也将非常好!:-)

编辑:澄清:基本上我和C#(object)v产量一样。我已经尝试过 enumToObject方法,但不幸的是,虽然这在 .NET 中可能工作正常,但在 C++ 端,我只取回 32 位整数值。C++ 方面的问题是,将整数作为 eg 的第三个参数传递会MessageBox.Show失败,大概是因为 .NET 方面的默认绑定器不会将其转换为枚举类型,所以我怀疑需要一个合适类型的引用对象实际论证。

0 投票
3 回答
999 浏览

c# - 为什么委托逆变不能与值类型一起使用?

此代码段未在 LINQPad 中编译。

编译器的错误信息是:

'UserQuery.IsNull(object)' 没有重载匹配委托 'System.Func'

它适用于字符串数组,但不适用于int[]. 它显然与拳击有关,但我想知道细节。

0 投票
4 回答
359 浏览

.net - 有没有办法衡量装箱/拆箱处罚?

我正在使用一个框架,该框架使用从System.Collections.CollectionBase. 用户一直在抱怨性能,我觉得这些使用非常频繁的集合可能是问题的很大一部分。有没有一种方法可以使用工具或分析器或在 IL 中获得一些关于装箱/拆箱处罚的指标?我需要证据来支持推动System.Collections.Generic。我已经尝试过 CLRProfiler,但往往会迷路并且不确定我应该寻找什么。

更新
感谢大家迄今为止的意见。我知道这可能不是主要瓶颈,但我正在寻找尽可能多的性能杀手的指标。这只是其中之一,不确定它有多大,因此寻找一种方法来测量它。

0 投票
4 回答
162 浏览

c# - 将 ValueType 声明为类的一部分时是否会被装箱?

考虑到这个类:

我猜“MyField”成员不在线程堆栈上,因为它可以被多个线程访问,它必须肯定在托管堆中,但这是否意味着它每次使用时都被装箱和拆箱?

提前致谢

0 投票
6 回答
821 浏览

java - 与 Java 不同,为什么在 .NET 中对原始值类型进行装箱是未缓存的?

考虑:

显然,每条装箱指令都分配了一个单独的装箱实例Int32,这就是它们之间的引用相等性失败的原因。此页面似乎表明这是指定的行为:

box 指令将“原始”(未装箱)值类型转换为对象引用(O 类型)。这是通过创建一个新对象 并将数据从值类型复制到新分配的对象中来实现的。

但是为什么一定要这样呢?是否有任何令人信服的理由说明 CLR 不选择Int32为所有原始值类型(都是不可变的)保存装箱 s 的“缓存”,甚至更强大的通用值?我知道Java有这样的东西。

ArrayList在没有泛型的时代,对于主要由小整数组成的大数据,它不会对减少内存需求和 GC 工作量有很大帮助吗?我也确信存在几个确实使用泛型的现代.NET 应用程序,但无论出于何种原因(反射、接口分配等),运行大型装箱分配,可以通过(似乎是)大量减少简单的优化。

那么是什么原因呢?我没有考虑到一些性能影响(我怀疑测试该项目是否在缓存中等是否会导致净性能损失,但我知道什么)?实施困难?不安全代码的问题?打破向后兼容性(我想不出一个好的程序应该依赖现有行为的任何充分理由)?或者是其他东西?

编辑:我真正建议的是“常见”原语的静态缓存,就像 Java 所做的那样。有关示例实现,请参阅 Jon Skeet 的回答。我知道在运行时对任意、可能可变的值类型或动态“记忆”实例执行此操作是完全不同的事情。

编辑:为清楚起见更改了标题。