为什么我不能在扩展方法中更新字符串的值?
Why can't I update the value of a string in an extension method?
我正在尝试创建一个扩展方法来简化我经常使用的一小部分代码:
var test = "this is a test.";
var substring = test.Substring(0, 4);
test = test.Remove(0, 4).Trim();
在 运行 上述代码片段并将 test
和 substring
的结果值打印到控制台 window 之后,您将看到:
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();
让我们不要学究气,不要专注于我可以在这里按空格拆分的事实;这不是一个普遍的例子,它通常不关注单词而是特定的子字符串。
在网上浏览了一下之后,我明白了为什么 这对值类型不起作用( is a post on that), but string
is a reference type, though it's treated as a value type in many cases (here 是 post话题)。这是另一种情况吗?如果是,为什么?
为什么我不能在扩展方法中更新字符串的值?
我不是在寻找替代方案,我试图理解为什么这不起作用,因为 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
扩展方法的第一个参数不支持修饰符。
我正在尝试创建一个扩展方法来简化我经常使用的一小部分代码:
var test = "this is a test.";
var substring = test.Substring(0, 4);
test = test.Remove(0, 4).Trim();
在 运行 上述代码片段并将 test
和 substring
的结果值打印到控制台 window 之后,您将看到:
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
is a reference type, though it's treated as a value type in many cases (here 是 post话题)。这是另一种情况吗?如果是,为什么?
为什么我不能在扩展方法中更新字符串的值?
我不是在寻找替代方案,我试图理解为什么这不起作用,因为 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
扩展方法的第一个参数不支持修饰符。