c# - 为什么我不能在扩展方法中更新字符串的值?
问题描述
我正在尝试创建一个扩展方法来简化我经常使用的一小部分代码:
var test = "this is a test.";
var substring = test.Substring(0, 4);
test = test.Remove(0, 4).Trim();
test
在运行上述代码片段并将结果值打印substring
到控制台窗口后,您将看到:
this
is a test.
我想用一个扩展方法来简化它,这将是一个有效的重载Substring
:
public static string Substring(this string input, int startingIndex, int length, bool removeFromInput = false) {
var substring = input.Substring(startingIndex, length);
if (removeFromInput)
input = input.Remove(startingIndex, length);
return substring;
}
这将允许我的代码向前简化为:
var test = "this is a test.";
var firstWord = test.Substring(0, 4, removeFromInput: true).Trim();
var secondWord = test.Substring(0, 2, removeFromInput: true).Trim();
var thirdWord = test.Substring(0, 1, removeFromInput: true).Trim();
var lastWord = test.Substring(0, 4, removeFromInput: true).Trim();
让我们不要学究气,专注于我可以在这里分割空白的事实;这不是一个普遍的例子,而且它通常不关注单词,而是关注特定的子字符串。
在网上浏览了一下之后,我明白了为什么这不适用于值类型(这里有一篇文章),但string
它是一种引用类型,尽管在许多情况下它被视为值类型(这里是一篇文章关于主题)。这是另一种情况吗?如果是这样,为什么?
为什么我不能在扩展方法中更新字符串的值?
我不是在寻找替代品,我试图理解为什么这不起作用,因为string
它是一个引用类型。我的替代实现是test.Substring(0, 4, removeFrom: ref test)
我认为仍然很好读的。
解决方案
这里的问题是,虽然string
是引用类型,但是当您将参数传递给方法时,引用会被复制。因此创建了一个指向内存中相同对象的新变量。当您使该变量指向一个新对象时,它不会影响原始对象。
这是一个示例来阐明我的意思:
var foo = "foo";
var bar = foo;
bar = "bar";
我们创建一个字符串并将它的引用存储在foo
变量中。然后我们创建一个bar
变量并将其引用存储foo
在其中。这是引用的副本,现在 2 个变量指向同一个对象。
当我们创建一个新字符串并将其分配给 时bar
,它不会影响 foo。现在bar
只是持有对不同对象的引用。
有一种方法可以做到修改原始参数而不复制引用,可以通过使用ref
参数来完成。但据我所知ref
,扩展方法的第一个参数不支持修饰符。
推荐阅读
- python - 无法从输入中导入协议
- c# - Azure Cosmos MongoDB - 使用分片键创建集合
- android - Autostart permission programmatically
- excel - Excel Countif 函数选择离散的单元格范围
- ruby-on-rails - 使用carrierwave-video 上传.MOV 文件?
- javascript - 做前端 2 年了,仍然不确定何时/如何使用类
- activemq-artemis - JMS 主题订阅者在未连接时不会收到消息
- android - 如何在不使用任何构建工具的情况下使用 aapt2 编译 Android 应用程序?
- php - 是否可以在 PHP MYSQL 中存储可点击的图像?
- svg - svg 在浏览器和 imagemagick 中呈现不同(使用 rsvg 转换)