首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取一个字符串来引用C#中的另一个字符串

获取一个字符串来引用C#中的另一个字符串
EN

Stack Overflow用户
提问于 2014-05-20 10:57:31
回答 8查看 2.1K关注 0票数 12

我来自C++背景。这个问题以前曾被问过,但尽管我可能会尝试,但我找不到答案。假设我有:

代码语言:javascript
运行
复制
string[] ArrayOfReallyVeryLongStringNames = new string[500];
ArrayOfReallyVeryLongStringNames[439] = "Hello world!";

我可以创建一个引用上述内容的字符串(这两个字符串都不会编译):

代码语言:javascript
运行
复制
string a = ref ArrayOfReallyVeryLongStringNames[439];  // no compile
string a = &ArrayOfReallyVeryLongStringNames[439];     // no compile

我理解字符串在C#中是不可变的。我还了解到,您无法获得托管对象的地址。

我想这么做:

代码语言:javascript
运行
复制
a = "Donkey Kong";  // Now ArrayOfReallyVeryLongStringNames[439] = "Donkey Kong";

我读过堆栈溢出问题https://stackoverflow.com/questions/10005351/c-sharp-make-a-reference-to-another-string,它有一个很好的答案,但问题略有不同。我不想通过引用将这个参数传递给函数。我知道如何使用"ref“关键字通过引用传递参数。

如果答案是“您不能在C#中这样做”,那么有一个方便的解决办法吗?

编辑:一些答案表明这个问题不清楚。让我们以另一种方式问它。假设我需要操作原始长名数组中所有具有主要索引的项。我想将别名添加到数组.2、Array.3、Array.5等列表中。然后,使用"for“循环修改列表中的项(可能是将刚刚创建的列表传递给函数)。

在C#中,“使用”关键字为类或命名空间创建别名。然而,从答案来看,不可能为变量创建别名。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2014-05-20 11:04:24

你能得到的最接近的是:

代码语言:javascript
运行
复制
unsafe
{
    string* a = &ArrayOfReallyVeryLongStringNames[439];     // no compile
}

这给了一个例外:

无法获取托管类型的地址、大小或声明指向托管类型(“字符串”)的指针

所以不不可能..。

还可以阅读这个MSDN文章,它解释了可以使用哪些类型(闪存类型)。

票数 5
EN

Stack Overflow用户

发布于 2014-05-20 11:14:58

您可以创建一个包装器,它保存对基础数组和字符串索引的引用:

代码语言:javascript
运行
复制
public sealed class ArrayStringReference
{
    private readonly string[] _array;
    private readonly int      _index;

    public ArrayStringReference(string[] array, int index)
    {
        _array = array;
        _index = index;
    }

    public string Value
    {
        get
        {
            return _array[_index];
        }

        set
        {
            _array[_index] = value;
        }
    }

    public override string ToString()
    {
        return Value;
    }
}

那么,这将是可行的:

代码语言:javascript
运行
复制
    string[] ArrayOfReallyVeryLongStringNames = new string[500];
    ArrayOfReallyVeryLongStringNames[439] = "Hello world!";

    var strRef = new ArrayStringReference(ArrayOfReallyVeryLongStringNames, 439);
    Console.WriteLine(ArrayOfReallyVeryLongStringNames[439]); // Outputs "Hello world!"
    strRef.Value = "Donkey Kong";
    Console.WriteLine(ArrayOfReallyVeryLongStringNames[439]); // Outputs "Donkey Kong"

通过提供一个隐式字符串运算符,您可以更方便地使用它,这样您就不必使用.Value来访问底层字符串:

代码语言:javascript
运行
复制
// Add this to class ArrayStringReference implementation

public static implicit operator string(ArrayStringReference strRef)
{
    return strRef.Value;
}

然后,不必像这样访问底层字符串:

代码语言:javascript
运行
复制
strRef.Value = "Donkey Kong";
...
string someString = strRef.Value;

你可以这样做:

代码语言:javascript
运行
复制
strRef.Value = "Donkey Kong";
...
string someString = strRef; // Don't need .Value

这只是语法上的糖,但它可能使在现有代码中开始使用ArrayStringReference变得更容易。(请注意,仍然需要使用.Value来设置基础字符串。)

票数 12
EN

Stack Overflow用户

发布于 2014-05-20 11:01:42

当我在C#中做这样的事情时:

代码语言:javascript
运行
复制
string a = "String 1";
string b = a;
a = "String 2";

Console.WriteLine(a); // String 2
Console.WriteLine(b); // String 1

问题是,"String 1“和"String 2”文字都是在程序开始时创建的,而字符串始终是指针:首先引用"String 1“文字,然后引用"String 2”。如果希望它们总是引用相同的东西,那么在C#中只使用相同的变量。

字符串对象本身在C#中是不可变的。

因为字符串“修改”实际上是一个新的字符串创建,所以在创建对字符串的引用时必须小心。如果创建对字符串的引用,然后“修改”原始字符串,则引用将继续指向原始对象,而不是在修改字符串时创建的新对象。

例如,当需要字符串可变性以更快地连接许多字符串时,就会使用其他类,比如StringBuilder

总之,你想做的事是不可能的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23757910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档