问题标签 [value-type]

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 投票
19 回答
450746 浏览

.NET 中的结构和类有什么区别?

.NET 中的结构和类有什么区别?

0 投票
6 回答
101236 浏览

更改结构列表中元素的值

我有一个结构列表,我想更改一个元素。例如 :

现在我想改变一个元素:

但是,每当我尝试这样做时,都会出现以下错误:

无法修改 System.Collections.Generic.List.this[int]' 的返回值,因为它不是变量

如果我使用类列表,则不会出现问题。

我想答案与结构是一种值类型有关。

那么,如果我有一个结构列表,我应该将它们视为只读吗?如果我需要更改列表中的元素,那么我应该使用类而不是结构吗?

0 投票
4 回答
18701 浏览

你可以在结构中有一个类吗?

在 C# 中是否可以有一个带有类类型成员变量的 Struct?如果是这样,信息存储在哪里,在堆栈、堆或两者上?

0 投票
7 回答
8685 浏览

为什么 .NET 中没有 RAII?

作为一名 C++ 开发人员,Java 和 .NET 中缺少RAII(资源获取即初始化)一直困扰着我。清理的责任从类编写者转移到其消费者(通过try finally.NET 的using构造)这一事实似乎明显逊色。

我明白为什么在 Java 中不支持 RAII,因为所有对象都位于堆上,而垃圾收集器本身不支持确定性销毁,但在 .NET 中引入了值类型(struct)我们有(似乎) RAII 的完美候选人。在堆栈上创建的值类型具有明确定义的范围,并且可以使用 C++ 析构函数语义。但是,CLR 不允许值类型具有析构函数。

我的随机搜索发现了一个论点,即如果一个值类型被装箱,它就属于垃圾收集器的管辖范围,因此它的销毁变得不确定。我觉得这个论点不够有力,RAII 的好处大到足以说明带有析构函数的值类型不能被装箱(或用作类成员)。

长话短说,我的问题是:是否有任何其他原因不能使用值类型来将 RAII 引入 .NET?(或者你认为我关于 RAII 明显优势的论点有缺陷吗?)

编辑:我一定没有清楚地表达这个问题,因为前四个答案没有抓住重点。我知道它的非确定性Finalize特征,我知道using构造,我觉得这两个选项不如 RAII。using类的消费者还必须记住一件事(有多少人忘记将 aStreamReader放在一个using块中?)。我的问题是关于语言设计的哲学问题,为什么它是这样的,可以改进吗?

例如,使用通用的确定性可破坏值类型,我可以使usingandlock关键字变得多余(可通过库类实现):


我不禁以我曾经看过但目前无法找到其来源的恰当报价作为结尾。

当我冰冷的死手超出范围时,您可以承担我的确定性破坏。——匿名

0 投票
5 回答
493 浏览

对任意值类型的操作

本文描述了一种在 C# 中允许添加具有为它们定义的 + 运算符的任意值类型的方法。本质上它允许以下代码:

此代码无法编译,因为无法保证 T 类型具有“+”运算符的定义,但使用如下代码可以实现效果:

按照链接查看 Num 类是如何实现这一点的。无论如何,关于这个问题。有什么方法可以在 C 或 C++ 中实现相同的效果?出于好奇,我试图解决的问题是允许 CUDA 内核通过允许它在更多类型上运行来更加灵活/通用。

更新:对于 .NET,Marc Gravell 制作了一个实用程序库,可以非常优雅地解决操作员问题。

0 投票
3 回答
1592 浏览

如何修改方法内的装箱值类型

我正在尝试构建一个库来简化 C# 中的后期绑定调用,但我在使用参考参数时遇到了麻烦。我有以下方法来添加方法调用中使用的参数

这不适用于值类型,因为它们被装箱为对象,因此它们不会被修改。例如:

那是行不通的。后期绑定调用成功,保存参数(_parameters)的内部列表确实被修改,但调用外部的值没有被修改。

有谁知道克服这个限制的简单方法?无法修改 AddParameter 签名,与后期绑定调用一样,您无法提前知道参数的类型(以及在调用之前将调用的所有参数插入对象数组中的任何一种方式)

提前致谢。

0 投票
4 回答
5031 浏览

C#中如何判断一个字符串是否为数字

我正在开发一个工具,我需要将字符串值转换为正确的对象类型。例如,将字符串转换"2008-11-20T16:33:21Z"DateTime值。"42"像和这样的数值"42.42"必须分别转换为一个Int32值和一个Double值。

检测字符串是整数还是数字的最佳和最有效的方法是什么?是Int32.TryParseDouble.TryParse要走的路吗?

0 投票
5 回答
2937 浏览

C# - 如何确保我的所有结构都已初始化?

我正在用 C# 编写一个应用程序,它将进行大量计算。一切都围绕着基本结构——价值。它基本上是双倍的,带有一些额外的参数(精度等)。它必须是一个结构,因为会创建太多的结构来提供堆分配。现在,我需要确保它们都已正确初始化。我不能声明默认的显式构造函数,尽管我提供了默认构造函数,它用 0 初始化所有内容,这在我的域中没有意义。

如果不使用参数调用我的构造函数,就无法拒绝创建实例......?

基本上我需要的是通过这个测试:

如果没有显式调用构造函数并且仍然访问结构,则抛出异常是可以的,但是检查所有时间将花费太多时间。

我现在几乎失去了希望,请帮助!

0 投票
2 回答
863 浏览

ValueType 包装器的垃圾收集

MSDN 链接中引用 ValueType 类

如果值类型必须表现得像对象,则在堆上分配一个使值类型看起来像引用对象的包装器,并将值类型的值复制到其中。包装器被标记以便系统知道它包含一个值类型。

这意味着当我编写像“integerVariable.ToString();”这样的代码时 创建的包装对象允许使用此方法以及 System.Object 的所有其他方法。

这种理解正确吗?

这些对象与“常规”对象有何不同?

此类对象的垃圾收集是否不同?如果是,如何?

提前致谢。

0 投票
4 回答
2809 浏览

对值类型调用方法会导致 .NET 中的装箱吗?

我刚刚参加 Stack Overflow 问题.NET 中的所有内容都是对象吗?.

一位发帖人(在接受答案的评论中)似乎认为对值类型执行方法调用会导致装箱。他向我指出了Boxing and Unboxing (C# Programming Guide),它并没有准确地指定我们正在描述的用例。

我不是一个相信单一来源的人,所以我只是想获得关于这个问题的进一步反馈。我的直觉是没有拳击,但我的直觉确实很糟糕。:D

进一步阐述:

我使用的示例是:

如果所讨论的结构覆盖从对象继承的方法,则不会发生装箱,因为此处接受的答案表明。

但是,如果结构没有覆盖该方法,则会在 callvirt 之前执行“约束” CIL命令。根据文档OpCodes.Constrained Field这会导致装箱

如果 thisType 是一个值类型并且 thisType 没有实现方法,则 ptr 被取消引用,装箱,并作为“this”指针传递给 callvirt 方法指令。