Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中字符串的行为# 我是C++程序员,现在正在研究一个C项目。_C# - Fatal编程技术网

C# C语言中字符串的行为# 我是C++程序员,现在正在研究一个C项目。

C# C语言中字符串的行为# 我是C++程序员,现在正在研究一个C项目。,c#,C#,在下面的代码片段中,我试图理解为什么即使函数正在更改其值,字符串的值也不会更改,我认为它是一个对象,并且会作为引用传递 public class TestClass { public TestClass(String passedStr) { passedStr = "Change me"; } } class Program { static void Main(string

在下面的代码片段中,我试图理解为什么即使函数正在更改其值,字符串的值也不会更改,我认为它是一个对象,并且会作为引用传递

public class TestClass
    {
        public TestClass(String passedStr)
        {
            passedStr = "Change me";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            String aString="I am what i am";
            TestClass obj = new TestClass(aString);
            Console.WriteLine(aString);

        }
    }
但是用户定义类的行为是不同的

 public class TestClass
    {
        private int x;
        public int ID
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }
        public TestClass(int a)
        {
            x = a;
        }
    }
    public class Tester
    {
        public Tester(TestClass obj)
        {
            obj.ID = 999;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            TestClass obj = new TestClass(555);
            Tester tester = new Tester(obj);
            Console.WriteLine(obj.ID);
        }
    }

不,它是按值传递的;没有
ref
关键字

传递引用类型(这里,类)>强>值> /强>(NO.<代码> REF关键字),就像传递C++中指针的副本一样。您正在重新分配指针,而不是实际的数据(无论如何,您不能使用字符串)

如果需要通过引用传递,请尝试:

    public TestClass(ref String passedStr)
    {
        passedStr = "Change me";
    }

    ...
    TestClass obj = new TestClass(ref aString);

您在构造函数中所做的是为局部变量
passedStr
分配一个新的字符串文本

在C中,等效函数如下所示:

Testclass constructor_testclass(char* passedStr) {
    passedStr = "Change me";
}

我认为很明显,此函数不会更改调用函数中的
char*
的值。

对象
我就是我
是通过引用传递的,但是重新分配给局部变量。您不更改原始对象,而是将一个新对象(
change me
)指定给参数的位置。

字符串通过引用传递,但指针通过C#中的值传递。如果要通过引用传递字符串,则必须使用关键字

例如:

public class TestClass
{
    public TestClass(ref string passedStr)
    {
        passedStr = "Change me";
    }
}

class Program
{
    static void Main(string[] args)
    {
        string aString="I am what i am";
        TestClass obj = new TestClass(ref aString);
        Console.WriteLine(aString); // "Change me"

    }
}

passedStr
不是字符串,而是保存字符串引用的构造函数参数。
TestClass
构造函数所做的一切就是更改此参数引用的字符串。它在构造函数之外没有效果

public class Employee
{
    public string ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return string.Format("ID = {0} Name = {1}", ID, Name);
    }
}

public class TestClass2
{
    public TestClass2(Employee e)
    {
        e.ID="007";
        e.Name="james";
    }
}  



static void Main()
{

    Employee e = new Employee();
    e.ID = "0";
    e.Name = "nobody";
    TestClass2 t = new TestClass2(e);
    Console.WriteLine(e); //Output ID = 007 Name = James 
}  
字符串是通过引用传递的,但指针是通过C中的值传递的#


让我们回到基础

变量是一个存储位置

string类型的变量是存储null或字符串引用的存储位置

“passedStr”和“aString”是不同的变量

调用“newtestclass(aString)”时,为“passedStr”创建一个新的存储位置,并将“aString”的内容复制到其中。现在有两个内容相同的变量:对字符串的引用

在构造函数中,您更改存储在“passedStr”存储位置中的值。“aString”保持不变


C#中的“ref”和“out”关键字表示“使形式参数和参数别名相互匹配”。在这种情况下,只有一个变量有两个不同的名称。当您更改其中一个时,另一个也会更改,因为它们是相同的变量。

如果我选择自己的书面课程,谢谢您的回复。我知道我不需要在参数类型中写入ref。默认情况下,它采用引用。什么是特例String@sat:在这方面,
String
没有什么特别之处——您介意发布代码,说明您所说的“我自己编写的类”是什么意思吗?@sat:是的,您正在传递一个引用。但是,您并没有更改引用的内容,而是将(本地)引用点设置为另一个字符串文本。关于C语言中的一个示例,请参见我的答案,您可能更熟悉这个示例。@sat:区别在于字符串实际上是C语言中的一个基本体。原语通过值传递,对象通过引用传递。因此,当您传递字符串时,您是按值传递字符串原语;当您传递自己的对象时,您是按引用传递对象。@sat:您的代码分配给
obj.ID
,而不是
obj
。C++等价物是 OBJ-> ID=…,这与<> Obj=…明显不同。如果
String.Length
不是只读的,它的行为也会是一样的。@Mehrdad:谢谢,我将从答案中删除它。