如何在c#中返回一个字符串的引用?

问题描述:

我期待写这样如何在c#中返回一个字符串的引用?

ref String TestIt(int index) 
{ 
return this.TestArray[index]; 
}; 

功能让喜欢我可以写代码:

MyClass.TestIt(0) = "Hello World"; 

我的目标是要模仿这个C++声明

CString& MyClass::Data(UINT index); 

通过引用我我指的是C++术语变量的地址。
换言之,在我致电TestIT(0) 后,TestArray [0]将包含“Hello World”。

编辑 ,因为我的目标是.cpp文件到C#转换持续的基础上,我不能使用索引。越接近我可以模仿这个C++代码,我不得不写的转换器越少。

要做到这一点,你需要编写一个setter属性。不幸的是,setter不能在C#中使用更多的参数,所以你不能在C#中编写1:1的代码。你可以得到的最接近的是一个默认属性嵌套类:

class YourClass { 
    public class Nested { 
     public Nested(YourClass outer) { m_RefToOuterWorld = outer; } 
     private readonly YourClass m_RefToOuterWorld; 

     public string this[int index] { 
      get { return m_RefToOuter.TestArray[index]; 
      set { m_RefToOuter.TestArray[index] = value; } 
     } 
    } 

    private readonly Nested m_Nested; 
    private string[] TestArray = new string[10]; 

    public YourClass() { m_Nested = new Nested(this); } 

    public Nested TestIt { get { return m_Nested; } } 
} 

您可以使用它像这样:

var test = new YourClass(); 
test.TestIt[2] = "Hello world!"; 

顺便说一句,因为这是这么多的努力,你可能穿上”不想这样做。另外,它不会感觉非常C#-y。这里通过嵌套类的无用indiretion不是你经常会看到的东西。

+0

基于我的VB背景,我开始为他写一个简单的索引属性,就像这样。然后我发现虽然VB.Net支持开箱即用,但C#要求您创建一个全新的类。游民。 – 2008-11-17 21:21:41

+0

真的很无聊。说实话,我从来不需要这个特定的VB功能。它主要用于模仿隐式CType运算符的语义,所以我们可以使用它。 – 2008-11-17 22:57:01

你不需要返回一个参考来实现你的目标。字符串类型是引用类型,但具有特殊的比较处理。所以如果你只是从TestIt返回一个字符串,相等性检查将做一个字符串比较。

+0

这不是一个字符串比较 - 它试图成为一个任务,因此将无法正常工作。 – 2008-11-17 21:24:25

简短的回答是,您不能返回对字符串变量的引用,即对字符串引用的引用)。

简单的解决办法是避免这种API,并要求用户设置以另一种方式的字符串:

myobj.SetString(0, "Hello, world!"); 

如果你真的需要代表(作为第一类对象)一参考你的字符串参考,尝试像这样的API:

Interface IStringReference 
{ 
    void SetString(string value); 
    string GetString(); 
} 


class MyClass 
{ 
    public IStringReference TestIt() 
    { 
     ... details left out ;) ... 
    } 
} 

但我认为这是模仿C++的左值太过分了。

难道你不只是使用索引器(一个匿名财产,需要参数)?

private string []storage = new string[10]; 
public string this[int index] 
{ 
    get 
    { 
    return storage[index]; 
    } 
    set 
    { 
    storage[index] = value; 
    } 
} 

,然后调用:

MyClass[0] = "Hello World"; 

当然,它没有花哨“的TestIt”名称标签...你需要一个名称标签吗?

编辑:大声笑,我搜索了“C#命名索引”,我在2005年发现回答愚蠢的问题和优秀的答案谁?除Jon Skeet之外无其他。

+0

对你的编辑:这也难怪,因为你可以谷歌*任何*搜索词包含“C#”,并找到(优秀)由乔恩答案。男人,这个人很无聊,可以预测。 – 2008-11-17 22:59:31

我可以建议更换以下sollution

public class Test 
    { 
     Dictionary<int,string> str=new Dictionary<int,string>(); 
     public string this[int i] 
     { 
      get 
      { 
       return str[i]; 
      } 
      set 
      { 
       if(!str.ContainsKey(i)) 
        str.Add(i,value); 
       else 
        str[i] = value; 
      } 
     } 

何苦让2个版本的代码是否一致?编写一个托管的C++包装器,你可以在.Net中使用,然后调用相应的函数,是不是更容易?

+0

我需要一个持续的基础上的业务逻辑,我已经在混合模式程序集中有这个,但有时MFC会很有趣,我希望100%托管代码能够为我的服务器提供强大的稳健性。 – 2008-11-17 23:24:13

所有相同的字符串只有一个引用,无论它在代码中引用了多少次。

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

公共语言运行库通过维护表节省 字符串存储, 叫实习生池,包含 一个参考声明或创建 编程每个唯一 文字字符串你程序。 因此,在系统中仅存在一次具有特定值 字符串的实例,该实例只存在一次 。

例如,如果您分配相同 文字串几个变量, 运行时检索来自 实习生池相同 参考文本字符串,并将其分配给每个 变量。