[转载]C#程序员请不要混淆引用类型和ref引用传参

转载C#程序员请不要混淆引用类型和ref引用传参 – slmk – 博客园.

先看一段代码1:

static void Main(string[] args)
{
StringBuilder sb = new StringBuilder("1");
test(sb);
Console.WriteLine(sb.ToString());
Console.Read();
}

static void test(StringBuilder sb)
{
sb = new StringBuilder("2");
}

错误的观念:

程序输出”2″,因为StringBuilder是引用类型,函数内部sb变量重新指向了托管堆中的新对象,函数返回后,外部的sb变量也指向了这个新对象,因为是引用类型吗,我传的是引用。

在错误的观念中,认为 “ref引用传参” 仅对.net中的另一种基本类型–值类型有用。

这种错误观念通常源于这样的经验,看代码2:

static void Main(string[] args)
{
StringBuilder sb = new StringBuilder("1");
test(sb);
Console.WriteLine(sb.ToString());
Console.Read();
}

static void test(StringBuilder sb)
{
sb.Append("2");
}

我们通常会很自豪的说:“看吧,程序输出12,这就是引用类型的特点,如果换成值类型就不是了!”。我们得出的结论并没有错,实际上,这正是引用类型的特点!然而将这个观念扩大到代码1的情况,就错了!
正确的理解:

程序正确的输出是“1”,并没有因为StringBuilder是引用类型,就应该输出“2” 。如果要输出“2”,需要加ref:

static void Main(string[] args)
{
StringBuilder sb = new StringBuilder("1");
test(ref sb);
Console.WriteLine(sb.ToString());
Console.Read();
}

static void test(ref StringBuilder sb)
{
sb = new StringBuilder("2");
}

对于ref传参,只要记住一点:对于值类型来说传的是值的地址,对于引用类型来说传的是地址的地址。
对于引用类型,同样记住一点:引用类型本身的地址是一个值类型。就像我们学习c时,指针本身的地址就是一个int。

好吧,用c来理解C#果然有点拗! 直观的理解:引用类型对象本身不改变,只改变对象的属性时,我们在操作同一个对象;如果连对象本身都可能会改变,就用ref传引用类型的对象吧!
为什么不用strng作测试呢?

因为string对象虽然是引用类型,但不能改变对象的属性CharArray,每次返回的都是新对象(看起来像值类型,其实不是!)。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏