在C#中传递和存储指向不可变类型和字符串的指针

时间:2009-02-19 20:01:55

标签: c# function pointers arguments immutability

有没有办法在C#中存储指向不可变类型的指针,比如字符串? 如何执行:   Instance1.SomeFunction(out MyString);

,并在Instance1中存储指向MyString的指针?

4 个答案:

答案 0 :(得分:0)

我一直在与C#中的指针作斗争一段时间,并且对于缺乏选择感到惊讶。在C#中处理指针和指针参数时会遇到各种模糊的障碍:

  • 您无法创建托管类型的本机指针,甚至不能创建字符串
  • 您无法保存不可变的out / ref-arguments供以后使用
  • 你不能有可选/可空的out / ref-arguments,即使“null”是字符串类型的默认状态
  • 你不能在lambda表达式中使用传递/ ref-arguments

我最近发现的非常简洁的解决方案,以及这篇文章的原因是:

void Test()
{
  string ret = "";
  SomeFunction(a=>ret=a);
}

void SomeFunction(string_ptr str)
{
   str("setting string value");
}

delegate void string_ptr(string a);

答案 1 :(得分:0)

使用此类作为指针(注意:未经测试的记事本代码,可能需要一些修复):

public class Box<T> {
    public Box(T value) { this.Value = value; }

    public T Value { get; set; }

    public static implicit operator T(Box<T> box) {
        return box.Value;
    }
}

例如,

public void Test() {
    Box<int> number = new Box<int>(10);
    Box<string> text = new Box<string>("PRINT \"Hello, world!\"");

    Console.Write(number);
    Console.Write("    ");
    Console.WriteLine(text);

    F1(number, text);

    Console.Write(number);
    Console.Write("    ");
    Console.WriteLine(text);
    Console.ReadKey();
}

void F1(Box<int> number, Box<string> text) {
    number.Value = 10;
    text.Value = "GOTO 10";
}

应输出

10    PRINT "Hello, world!"
20    GOTO 10

答案 2 :(得分:0)

关于提问者的回答,有什么问题:

class Program
{
    static void Main()
    {
        string str = "asdf";
        MakeNull(ref str);
        System.Diagnostics.Debug.Assert(str == null);
    }

    static void MakeNull(ref string s)
    {
        s = null;
    }

}

答案 3 :(得分:0)

好的,我找到了另一个解决我问题的部分方法。如果您希望某些ref / out-arguments具有空值,则可以使用重载:

void Test()
{
    string ret1 = "", ret2 = "";
    SomeFunction(ref ret1, ref ret2);
    SomeFunction(null, ref ret2);
    SomeFunction(ref ret1, null);
    SomeFunction(null,null);
}

string null_string = "null";

void SomeFunction(ref string ret1,ref string ret2)
{
   if( ret1!=null_string )
       ret1 = "ret 1";
   if( ret2!=null_string )
       ret2 = "ret 2";
}

// Additional overloads, to support null ref arguments
void SomeFunction(string ret1,ref string ret2)
{
    Debug.Assert(ret1==null);
    SomeFunction(null_string,ret2);
}
void SomeFunction(ref string ret1,string ret2)
{
    Debug.Assert(ret2==null);
    SomeFunction(ret1,null_string);
}
void SomeFunction(string ret1,string ret2)
{
    Debug.Assert(ret1==null&&ret2==null);
    SomeFunction(null_string,null_string);
}