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

C# 在C中传递和存储指向不可变类型和字符串的指针#,c#,function,pointers,arguments,immutability,C#,Function,Pointers,Arguments,Immutability,有没有办法在C#中存储指向字符串等不可变类型的指针? 如何执行: Instance1.SomeFunction(out MyString) ,并将指向MyString的指针存储在Instance1中?我已经用C#中的指针进行了一段时间的斗争,对于缺少选项感到惊讶。在C#中处理指针和指针参数时,会遇到各种模糊的障碍: 您不能创建指向托管类型的本机指针,甚至不能创建指向字符串的本机指针 不能保存不可变的out/ref参数以供以后使用 即使“null”是字符串类型的默认状态,也不能有可选/可为nul

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


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

我已经用C#中的指针进行了一段时间的斗争,对于缺少选项感到惊讶。在C#中处理指针和指针参数时,会遇到各种模糊的障碍:

  • 您不能创建指向托管类型的本机指针,甚至不能创建指向字符串的本机指针
  • 不能保存不可变的out/ref参数以供以后使用
  • 即使“null”是字符串类型的默认状态,也不能有可选/可为null的out/ref参数
  • 不能在lambda表达式中使用传递的/ref参数
我最近发现了一个非常简洁的解决方案,这篇文章的原因也是:

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

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

delegate void string_ptr(string a);

我在C#中与指针搏斗了一段时间,对没有选择感到惊讶。在C#中处理指针和指针参数时,会遇到各种模糊的障碍:

  • 您不能创建指向托管类型的本机指针,甚至不能创建指向字符串的本机指针
  • 不能保存不可变的out/ref参数以供以后使用
  • 即使“null”是字符串类型的默认状态,也不能有可选/可为null的out/ref参数
  • 不能在lambda表达式中使用传递的/ref参数
我最近发现了一个非常简洁的解决方案,这篇文章的原因也是:

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

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

delegate void string_ptr(string a);

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


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


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

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;
    }

}

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

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;
    }

}

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

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);
}

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

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);
}

委托不是指针——它是一个setter(你不能用它获取值)。这里是具有setter功能的委托:)static void Main(){string s=“s”;test(a=>s=a??s);}static void test(string_ptr s){string r1=s(null);s(“更改字符串”);string r2=s(null);}委托字符串字符串_ptr(字符串a);*setter-ability->getter-ability并且委托不是指针-它是一个setter(你不能用它获取值)。这里是具有setter-ability的委托:)static void Main(){string s=“s”test(a=>s=a??s);}static void test(string_ptr s){string r1=s(null);s(“更改字符串”);字符串r2=s(null);}委托字符串_ptr(字符串a);*setter-ability->getter-abilityC似乎被设计为对程序员隐藏指针。一般来说,指针操作不必要地使C#代码复杂化,因为通常有一种简单得多的方法来执行您想要的操作;静态void test1(ref string s){r=s;}静态void test2(){r=“changed string”}不,但您是对的。C#中不需要指针。我的问题更多的是理论性的。我只是想用C#编写C代码,尽管这是可能的,因为新语言至少实现了某种本机指针。C#似乎是为了对程序员隐藏指针而设计的。一般来说,指针操作不必要地使C#代码复杂化,因为通常有一种简单得多的方法来执行您想要的操作;静态void test1(ref string s){r=s;}静态void test2(){r=“changed string”}不,但您是对的。C#中不需要指针。我的问题更多的是理论性的。我只是试着用C#编写C代码,尽管这是可能的,因为新语言至少实现了某种本机指针。对我来说,将所有字符串和int变量重命名为box和box听起来需要做很多工作。可能是我太懒了……)想象一下,这个框是C#的int*语法。我相信这是你能找到的唯一的指针替代品。等等,这是完全错误的。构造长方体时,不再引用原始字符串。你在复制它!对框的
值的修改将不会更新您所引用的原始字符串。不,作为
ref string
传递它没有任何区别。你需要找到一些不同的模型来做这件事。我从来没有说过它会更新原始字符串。该框允许您在其中存储字符串,这样您就可以像存储字符串指针一样改变值。您可以通过这种方式获得一个引用类型值,该值可以传递、复制到类中,等等,并且与同一个引用保持可变。我们的想法不是制作一个
string
变量和一个引用它的
Box
,而是只制作一个
Box
。对我来说,将所有字符串和int变量重命名为Box和Box听起来需要做很多工作。可能是我太懒了……)想象一下,这个框是C#的int*语法。我相信这是你能找到的唯一的指针替代品。等等,这是完全错误的。构造长方体时,不再引用原始字符串。你在复制它!对框的
值的修改将不会更新您所引用的原始字符串。不,作为
ref string
传递它没有任何区别。你需要找到一些不同的m