CLR 字符串引用不(始终)匹配

2024-02-14

来自里希特和这次讨论 https://stackoverflow.com/questions/8482479/why-are-2-separate-string-references-equal-in-other-words-why-are-s-and-t-both,我希望任何两个“相同”字符串都是相同的引用。但刚才在 LINQPad 中,我在这个主题上得到了好坏参半的结果。这是代码:

void Main()
{
    string alpha = String.Format("Hello{0}", 5);
    string brava = String.Format("Hello{0}", 5);
    ReferenceEquals(alpha, brava).Dump();
    String.IsInterned(alpha).Dump();
    String.IsInterned(brava).Dump();

    alpha = "hello";
    brava = "hello";
    ReferenceEquals(alpha, brava).Dump();
}

以下是 Dump() 调用的结果:

False
Hello5
Hello5
True

我本来期望第一个和最后一个ReferenceEquals to be True。发生了什么?

除了上面的示例之外,ReferenceEquals 在其他什么情况下会失败?例如,多线程?

例如,如果我使用传递到方法中的字符串参数作为锁定的对象,那么这个问题就很重要。在这种情况下,参考文献最好是相同的!


动态创建的字符串不会发生字符串驻留。这包括由 String.Format 和 StringBuilder 创建的那些(我相信 String.Format 在内部使用 StringBuilder )。 MSDN 的文档字符串实习生 http://msdn.microsoft.com/en-us/library/system.string.intern.aspx表明这一点:

在以下示例中,字符串 s1 的值为 “MyTest”已经被实习,因为它是程序中的文字。 System.Text.StringBuilder 类生成一个新的字符串对象 与 s1 具有相同的值。对该字符串的引用被分配给 s2。 Intern 方法搜索与以下值具有相同值的字符串 s2。因为存在这样的字符串,所以该方法返回相同的 分配给 s1 的引用。然后将该引用分配给 s3。引用 s1 和 s2 比较不相等,因为它们引用 不同的对象;引用 s1 和 s3 比较相等,因为它们 引用同一个字符串。

string s1 = "MyTest";
string s2 = new StringBuilder().Append("My").Append("Test").ToString();  
string s3 = String.Intern(s2);  
Console.WriteLine((Object)s2==(Object)s1); //Different references. 
Console.WriteLine((Object)s3==(Object)s1); //The same reference.

需要注意的关键一点是,对于 CLR 您生成的字符串string.Format("Hello{0}", 5)不被视为文字字符串,因此加载程序集时不会发生驻留。琴弦"hello"另一方面被 CLR 拘留。为了实习这些字符串,您必须使用 String.Intern 显式地执行此操作。

Edit

关于您的锁定问题,理论上您可以使用字符串作为锁定对象,但我认为这是不好的做法。您不知道传递给应用程序的字符串来自哪里,因此不能保证它们是相同的参考。这些字符串可能来自数据库读取调用、使用 StringBuilder、使用 String.Format 或用户输入。在这些情况下,您的锁定无法确保一次只有一个线程位于您的临界区中,因为不能保证发生字符串驻留。

即使你could保证您始终使用实习字符串,您仍然会遇到潜在的危险问题。现在,任何人都可以在应用程序中的任何位置(包括其他 AppDomain)锁定相同的字符串引用。这是个坏消息。

我建议有一个显式声明的锁对象(对象类型)。你将为自己节省一个ton调试线程问题(如果出现)的时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CLR 字符串引用不(始终)匹配 的相关文章

  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 为什么禁止在 constexpr 函数中使用 goto?

    C 14 对你能做什么和不能做什么有规则constexpr功能 其中一些 没有asm 没有静态变量 看起来相当合理 但标准也不允许goto in constexpr功能 即使它允许其他控制流机制 这种区别背后的原因是什么 我以为我们已经过去
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 网络参考共享类

    我用 Java 编写了一些 SOAP Web 服务 在 JBoss 5 1 上运行 其中两个共享一个类 AddressTO Web 服务在我的 ApplycationServer 上正确部署 一切都很顺利 直到我尝试在我的 C 客户端中使用
  • 将 System.Windows.Forms.Keys 序列转换为 Char

    有没有办法转换由 Keys 枚举表示的击键序列 即System Windows Forms Keys 在一个字符中 例如 Keys Oem4进而Keys A产生 char 它一定存在于 WinAPI 中的某个地方 因为当我在文本框中按下按键
  • 将应用程序从 Microsoft Access 迁移到 VB 或 C#.NET

    我目前正试图说服管理层需要将我们的应用程序之一移植到 NET 该应用程序已经发展成为 Access 中的一个庞然大物 SQL 后端 拥有 700 个链接表 650 个表单 子表单 130 个模块和 850 个查询 我几乎知道这样做的所有主要
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐

  • 优化容量利用率的算法

    我为自己设定了一个 简单 的 C 编程挑战 以优化容量 我第一次尝试时表现不佳 如下文所述 因此我想看看是否有一个标准化算法可以做到这一点 而不使用人工智能 启发式技术 因为我根本不知道它们 我相信有一种已知的方法可以做到这一点 因为该问题
  • Rails 4 中 before_action 返回 false 有何作用?

    我正在阅读 使用Rails 4进行敏捷Web开发 第1页 338 它说 回调可以是被动的 监视控制器执行的活动 他们还可以更积极地参与请求处理 如果之前操作回调返回 false 则回调链的处理将终止 并且不会运行该操作 现在我的疑问如下 这
  • SQL Server 在一次调用中返回两次结果?

    我已将 SQL Server 数据库连接到简单的 Node js 服务器 当我运行代码时 我得到了记录集和返回给我的记录集 它们本质上都包含相同的数据 我可以使用这个 但它似乎多余 而且直接调用我需要的记录会更整洁 我希望得到一个清晰的 E
  • 初始化列表无法在 Visual Studio 2012 中使用矢量? [复制]

    这个问题在这里已经有答案了 可能的重复 Visual Studio 2012 中的 C 11 功能 https stackoverflow com questions 7421825 c11 features in visual studi
  • 如何向 bash 提示符添加图标

    我知道你可以通过编辑 bashrc 文件中的 PS1 变量来永久编辑 bash 提示符 我的如下所示 PS1 e 0 31m
  • Snakeyaml 似乎不必要地将简单值包装在列表中

    我正在尝试使用 Groovy 和 Snakeyaml 解析以下 YAML 文件 显然我已经清理了数据 但这足以证明问题 info summary Snakeyaml Issue examples 1st example name Examp
  • oracle SQL 如何从日期中删除时间

    我有一个名为StartDate包含以下格式的日期 03 03 2012 15 22 我需要的是将其转换为日期 它应该看起来像这样 DD MM YYYY 我尝试过但没有成功的是 select p1 PA VALUE as StartDate
  • 自定义流利验证器

    我对使用 fluidvalidator 非常陌生 我所知道的只是基本的rulefor 但说到习惯我就完全无能为力了 有人可以指导我吗 我需要验证可为空的布尔属性 我需要比较 5 个 bool 属性 如果至少选择了其中之一 则它应该返回 tr
  • IntelliJ 不理解 Java9-ea 上的 java 库

    我在用jdk9 ea 149并创建了一个样本javafx应用程序 IntelliJ不理解java库 它显示了所有导入语句红色他们都是变灰 即使是java util List java util ArrayList它有同样的问题 我可以在外部
  • 如何在 SwiftUI 中创建此视图?

    I am trying to create a view like this in SwiftUI sorry it s so huge 具体来说 我试图在屏幕的顶部四分之一处构建滚动的标签 条形图栏行 对我来说 它看起来像一个水平滚动的
  • Keras 中的 CNN 模型条件层

    我正在尝试建立一个conditional CNN模型 模型是 At the first stage我的模型 我将数据提供给Model 1 then based on the prediction of Model 1 我想要train th
  • 如何使用 InteractionManager.runAfterInteractions 使导航器转换更快

    由于逻辑复杂 我必须渲染很多组件this props navigator push 缓慢的导航器转换使应用程序不可用 然后我注意到here http facebook github io react native docs performa
  • 将行添加到 Word 文档中的现有表(打开 XML)

    我需要打开包含现有表 例如 3 列 的现有 Word 文档 docx 并向该表添加新行 有什么办法可以做到这一点吗 我正在使用 Open XML 我正在创建这样的表 第一次 Table tbl new Table Set the style
  • 在等待挂起操作取消时处置 SemaphoreSlim 是否安全?

    我必须使用 SemaphoreSlim 来确保对代码某些部分的单线程访问 并且希望确保我正确处理所有内容 假设我有以下课程 public class Foo private readonly CancellationTokenSource
  • 如何在多种类型上使用 GraphQL 片段

    我有一个 Gatsby 项目 它对两种不同类型的内容有非常相似的 GraphQL 查询 常规页面和 wiki 文章 按块分页 export const query graphql query slug String page content
  • 使用 fft 和 ifft 更改频率而不使用整数

    我知道我可以通过改变变量来改变整数频率shift但我怎样才能改变频率使用带小数位的数字 例如 754 或 1 2345 or 67 456 如果我改变变量 shift 到一个非整数类似的数字5 1 我收到错误下标索引必须是小于 2 31 的
  • 验证 Google 地图中的某个点是陆地还是水域

    然后谷歌地图 将水域与水域分开 嗯 不是圣经意义上的 但是 我想知道我有哪些选项来验证 Lat Lon 的点是陆地还是水域 谷歌地图显然有这些数据 水体是蓝色的 但是 API 中有什么东西我可以用它来实现吗 如果没有 他们不提供服务是因为他
  • Android 中使用 ArrayAdapter 和 ListView 的大型数据集

    出于学习目的 我想编写一个 Android 应用程序 将显示从 0 到 Integer MAX VALUE 的数字列表 我目前有一个 应用程序将显示从 0 到 100 的数字 这很简单 因为您只需 创建一个数字数组 然后将其传递给适配器 当
  • Brightway2 - 获取即时交换的 LCA 分数

    我在对 Brightway2 的 LCA 结果进行后处理分析时遇到一些问题 运行 LCA 计算后 例如 如果我输入 top activities 我会得到一堆活动及其相关分数的列表 但是没有一个活动 分数与我的功能单元直接相关 它们似乎是我
  • CLR 字符串引用不(始终)匹配

    来自里希特和这次讨论 https stackoverflow com questions 8482479 why are 2 separate string references equal in other words why are s