4

好的,我知道这个问题非常简单,而且我承认我对 C# 也很陌生。但是标题并没有描述这里的整个情况,所以请听我说。

我需要更改在后面的 C# 代码中创建的 URL 字符串,从字符串末尾删除子字符串“.aspx”。所以基本上我知道我的 URL,进入这个类,会像“Blah.aspx”,我想去掉那个字符串的“.aspx”部分。我认为这很容易做到,只需找到那个子字符串,如果它存在就删除它(或者一些类似的策略,如果有人有一个优雅的解决方案,如果他们以前想过这样做,我会很感激)。这是问题所在:

“因为字符串是不可变的,所以不可能(不使用不安全的代码)在创建字符串对象后修改它的值。” 这是来自 MSDN 官方网站。所以我现在想知道,如果字符串真的是不可变的,那么我根本不能(不应该)在字符串创建后更改它。那么我怎样才能确保我计划做的事情是安全的呢?

4

4 回答 4

6

您不更改字符串,而是更改变量。而不是那个变量引用一个字符串,例如"foo.aspx",改变它指向一个新的字符串,该字符串具有值"foo"

打个比方,数字二加一不会改变数字二。两个仍然与往常一样,您已将变量从引用一个数字更改为引用另一个数字。

至于你的具体情况,EndsWith让它Remove变得足够简单:

if (url.EndsWith(".aspx"))
    url = url.Remove(url.Length - ".aspx".Length);

请注意,这里Remove取一个字符串,一个整数,并给我们一个全新的字符串,我们需要将其分配回我们的变量。它不会改变字符串本身。

另请注意,有一个URI类可用于解析 URL,它将能够处理可能出现的所有复杂情况,包括哈希、查询参数等。您应该使用它来解析您感兴趣的网址。

于 2013-08-12T19:45:46.633 回答
5

字符串不变性对于正常使用来说不是问题——它只是意味着像“替换”这样的成员函数,而不是修改现有的字符串对象,而是返回一个新对象。实际上,这通常意味着您必须记住将更改复制回原始版本,例如:

string x = "Blah.aspx";
x.Replace(".aspx", "");       // still "Blah.aspx"
x = x.Replace(".aspx", "");   // now "Blah"

字符串的奇怪之处在于,由于它的System.String不变性System.Object,它的行为类似于值类型而不是对象。例如,如果您将字符串传递给函数,则无法修改它,除非您通过引用传递它:

void Test(string y)
{
    y = "bar";
}
void Test(ref string z)
{
    z = "baz";
}
string x = "foo";
Test(x);                 // x is still "foo"
Test(ref x);             // x is now "baz"
于 2013-08-12T19:45:20.610 回答
2

正如您所说,C# 中的AString是不可变的。这意味着这将String在内存中创建多个对象:

String s = "String of numbers 0";
s += "1";
s += "2";

因此,虽然变量s会返回 value 给您String of numbers 012,但在内部它需要在内存中创建三个字符串才能完成。

在您的特定情况下,解决方案非常简单:

String myPath = "C:\\folder1\\folder2\\myFile.aspx";
myPath = Path.Combine(Path.GetDirectoryName(myPath), Path.GetFileNameWithoutExtension(myPath));

同样,这似乎myPath已经改变,但实际上并没有改变。发生了内部复制和分配,您可以继续使用相同的变量。

此外,如果您必须保留原始变量,您可以简单地创建一个新变量:

String myPath = "C:\\folder1\\folder2\\myFile.aspx";
String thePath = Path.Combine(Path.GetDirectoryName(myPath), Path.GetFileNameWithoutExtension(myPath));

无论哪种方式,您最终都会得到一个可以使用的变量。

请注意,使用这些方法可确保您获得正确的路径操作,而不是可能产生意外副作用的Path盲目替换。String

于 2013-08-12T19:54:35.300 回答
1

String.Replace()不会修改字符串。它将创建一个新的。所以下面的代码:

String myUrl = @"http://mypath.aspx";
String withoutExtension = myUrl.Replace(".aspx", "");

将创建一个分配给 withoutExtension 的全新字符串。

于 2013-08-12T19:46:31.620 回答