ref和out关键字

王子文龙 2014-03-06 11:29:30
不使用ref和out关键字:
值类型传递的是实例的副本,调用方法对其修改不会影响原先的实例
引用类型传递的是对对象的一个引用,我可以理解这个引用也是一个地址的副本吗?
两个地址指向同一个对象,如果对副本地址重新赋值,则修改不会对原先对象造成影响

使用ref和out关键字:
值类型传递的是实例的指针,调用方法可以通过指针对其进行修改
引用类型传递的还是对对象的一个引用吧?
如果重新赋值,在修改的话原先对象也会修改?怎么回事?

使用out关键字要求不允许实例化,对于引用类型可以实例化?怎么回事

大神请详细讲解一下呗,上面如果我的哪个观点不对也请指出来,谢谢了
...全文
217 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
BenBenBears 2014-03-07
  • 打赏
  • 举报
回复
“out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。”可以借助这句话进一步理解out和ref在使用上面的区别。

        public bool CheckUser(string UserName, out string PassWord, out int State)
        {
        if (UserName == "mh_ma")
        {
            PassWord = "123";
            State = 0;
        }
        else
        {
            PassWord = "";
            State = 1;
        }
        return false;
        }
这时候我们可以得到三个返回值。
BenBenBears 2014-03-07
  • 打赏
  • 举报
回复
关于“使用out关键字要求不允许实例化”,没有这样的约束,可能“使用out关键字参数外部不要求实例化,但方法返回之前必须为 out 参数赋值。”更合适些。
BenBenBears 2014-03-07
  • 打赏
  • 举报
回复
引用 8 楼 mh_ma 的回复:

ChangeType(ref Person per)
{
   per=new Person();
   per.Name="123";
}
ChangeType(Person per)
{
  per=new Person();
  per.Name="123";
}
这两个结果就不一样,我想知道这个为什么不一样,传递的都是地址,这个地址的区别
不加ref时,形参变量指向该实参变量在操作系统栈中的地址,可以理解为是地址的副本,当你new时相当于改变了形参变量所指向的地址,往下的操作对实参就没有影响了;加ref时,形参变量不仅指向该实参变量在操作系统栈中的地址,也指向该实参变量在操作系统堆中的地址,可以理解为实际上就是实参本身,当new时也相当于改变实参本身。 拙见,继续期待楼下的回答。
王子文龙 2014-03-07
  • 打赏
  • 举报
回复
[quote=引用 12 楼 kxm_2012 的回复:] [quote] 这个是我想要的
王子文龙 2014-03-06
  • 打赏
  • 举报
回复
引用 4 楼 mh_ma 的回复:
[quote=引用 1 楼 liuchaolin 的回复:] out是由内部进行附值(通道)
跟VS的版本有关系吗[/quote] 使用ref,必须初始化,使用out怎么着都行,但是方法里面必须初始化对吧
王子文龙 2014-03-06
  • 打赏
  • 举报
回复
引用 3 楼 UR_Not_Alone 的回复:
引用类型传递的是地址,修改副本会对原有对象产生影响,一起变
这个我知道,比如你看这个

ChangeType(ref Person per)
{
   per=new Person();
   per.Name="123";
}
ChangeType(Person per)
{
  per=new Person();
  per.Name="123";
}
这两个结果就不一样,我想知道这个为什么不一样,传递的都是地址,这个地址的区别
md5e 2014-03-06
  • 打赏
  • 举报
回复
是不是后来的版本就不懂了,我学.net前他就已经存在了
夜轻风 2014-03-06
  • 打赏
  • 举报
回复
因为,他们本来就是同一个东西
王子文龙 2014-03-06
  • 打赏
  • 举报
回复
引用 1 楼 liuchaolin 的回复:
out是由内部进行附值(通道)
跟VS的版本有关系吗
wuhaipinm 2014-03-06
  • 打赏
  • 举报
回复
使用的感觉 ref是方法内部可以不赋值,out是方法内部必须赋值,否则无法编译。 使用这些修饰符通常都是int,string这些非对象类,如果是对象,根本不需要ref和out,直接内部赋值外部也会改变
夜轻风 2014-03-06
  • 打赏
  • 举报
回复
引用类型传递的是地址,修改副本会对原有对象产生影响,一起变
王子文龙 2014-03-06
  • 打赏
  • 举报
回复
引用 1 楼 liuchaolin 的回复:
out是由内部进行附值(通道) int a=0; changeval(out a); 结果 ---- a=123 public void changeval(out int a){ a=123; }
这个是后来版本改的吗?我记得ref修饰的,必须初始化,而out修饰,不能初始化
md5e 2014-03-06
  • 打赏
  • 举报
回复
out是由内部进行附值(通道) int a=0; changeval(out a); 结果 ---- a=123 public void changeval(out int a){ a=123; }
zunzhi59 2014-03-06
  • 打赏
  • 举报
回复
原来如此,受教育了 !
魂之挽歌来袭 2014-03-06
  • 打赏
  • 举报
回复
引用 8 楼 mh_ma 的回复:
[quote=引用 3 楼 UR_Not_Alone 的回复:] 引用类型传递的是地址,修改副本会对原有对象产生影响,一起变
这个我知道,比如你看这个

ChangeType(ref Person per)
{
   per=new Person();
   per.Name="123";
}
ChangeType(Person per)
{
  per=new Person();
  per.Name="123";
}
这两个结果就不一样,我想知道这个为什么不一样,传递的都是地址,这个地址的区别[/quote] 是不一样的
public void Go()
          {
             Thing x = new Animal();
           
             Switcharoo(ref x);
 
              Console.WriteLine(
                "x is Animal    :   "
                + (x is Animal).ToString());
 
              Console.WriteLine(
                  "x is Vegetable :   "
                  + (x is Vegetable).ToString());
              
          }
 
           public void Switcharoo(ref Thing pValue)
           {
               pValue = new Vegetable();
           }
输出结果: x is Animal : False x is Vegetable : True 如果不用ref输出结果刚好相反。 是因为用了ref之后参数pValue指向栈上的变量x,执行Switcharoo方法后x的通过变量pValue指向了new Vegetable()的地址。而不用ref参数pValue只是栈上的变量x的一个复制。执行Switcharoo方法之后,pValue变成了new Vegetable()的地址,而x依然指向animal这个对象。
王子文龙 2014-03-06
  • 打赏
  • 举报
回复
引用 1 楼 liuchaolin 的回复:
out是由内部进行附值(通道)
传引用的方式传递参数,会为实参在栈上分配内存吗

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧