A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 翟盼盼 高级黑马   /  2013-3-7 12:49  /  2713 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

c#中ref和out的区别有哪些?

评分

参与人数 1技术分 +1 收起 理由
张文 + 1

查看全部评分

10 个回复

倒序浏览
http://www.cnblogs.com/gsk99/archive/2010/12/13/1904557.html
希望这个博客对你有用
回复 使用道具 举报
ref是传递参数的地址,out是返回值
使用ref前必须对变量赋值,out不用.out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

out类型参数是按地址传递,能改变原来的数值,使用out传参前,对变量可以赋值也可以不赋值。带有out类型参数的函数,会清空变量,所以在离开该函数的时候,所有out引用的变量都要赋值。

ref类型参数是按地址传递,能改变原来的数值,使用ref传参前,变量必须赋值,带有ref类型参数的函数,不会清空变量,所以离开该函数的时候,所有ref引用的变量可以赋值也可以不赋值。

评分

参与人数 1技术分 +1 收起 理由
张文 + 1

查看全部评分

回复 使用道具 举报
只想简单说一句主要区别:
out 不要求调用代码前 对要调用参数初始化,但必须在调用方法内修改;
ref 可以改也可以不改。
回复 使用道具 举报
ref(C# 参考)
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。

例如:

class RefExample

{

    static void Method(ref int i)

    {

        i = 44;

    }

    static void Main()

    {

        int val = 0;

        Method(ref val);

        // val is now 44

    }

}

传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。

尽管 ref 和 out 在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:

class CS0663_Example

{

    // Compiler error CS0663: "cannot define overloaded

    // methods that differ only on ref and out".

    public void SampleMethod(ref int i) { }

    public void SampleMethod(out int i) { }

}

但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载,如下例所示:

class RefOutOverloadExample

{

    public void SampleMethod(int i) { }

    public void SampleMethod(ref int i) { }

}



out(C# 参考)
out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。

例如:

class OutExample

{

    static void Method(out int i)

    {

        i = 44;

    }

    static void Main()

    {

        int value;

        Method(out value);

        // value is now 44

    }

}

尽管作为 out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。



ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:

class CS0663_Example

{

    // Compiler error CS0663: "Cannot define overloaded

    // methods that differ only on ref and out".

    public void SampleMethod(out int i) { }

    public void SampleMethod(ref int i) { }

}



但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:

class RefOutOverloadExample

{

    public void SampleMethod(int i) { }

    public void SampleMethod(out int i) { }

}

评分

参与人数 1技术分 +1 收起 理由
张文 + 1

查看全部评分

回复 使用道具 举报
下面分别对out和ref的使用方法根据实例进行说明

    第一个实例中,自己写MyTryParse方法,采用out关键字返回转换成功后int数值number。

        /// <summary>

        /// 写MyTryParse熟悉out关键字用法

        /// </summary>

        /// <param name="str">字符串</param>

        /// <param name="number">转换后输出值</param>

        /// <returns>是否转换成功</returns>

        public static bool MyTryParse(string str, out int number)

        {

            bool isOk = false;

            number = 0;

            try

            {

                number = Convert.ToInt32(str);

                isOk = true;

            }

            catch

            {



            }

            return isOk;

        }

    此函数实现功能与int.TryParse方法形同,将输入的字符串转换为int类型,若是转换成功,返回bool类型true,并同时返回转换后的int数值,若是转换失败,返回bool类型false,默认转换后数值为0。

    此例子采用out关键字将转换后的数值进行返回,在一个函数中,实现了返回多个返回值。



    第二个实例中,写FaKuan方法,要求罚款时,要求当月工资减500,同时年终奖减1000,函数调用完成后主函数变量值发生改变。

        static void Main(string[] args)

        {

            double salary = 5000;

            double nianZhongJiang = 20000;

            FaKuan(ref salary, ref nianZhongJiang);

            Console.WriteLine(salary);

            Console.WriteLine(nianZhongJiang);

            Console.ReadKey();

        }



        /// <summary>

        /// 此函数定义罚款规则,工资减500,同时年终奖减1000

        /// </summary>

        /// <param name="s"></param>

        /// <param name="nzj"></param>

        public static void FaKuan(ref double s, ref double nzj)

        {

            s -= 1000;

            nzj -= 1000;

        }

    通过使用ref关键字后,成功实现调用函数中变量值改变,ref的功能为将实参带入方法,方法运行结束后将值再带回调用函数。
回复 使用道具 举报
边亮 中级黑马 2013-3-11 21:22:18
7#
out 侧重是返回多个值,并不能带入值只能把方法中的值带出,在方法中必须为其赋值
ref 可以带入带出值,在方法外必须为其赋值。
回复 使用道具 举报
2、方法的参数,学习了两种为方法传递参数的方法:一是ref方式,二是值传递,三是out方式。
     ref侧重于修改,out更侧重与输出。
Out参数:

Out参数的主要作用,就是可以返回多个值。

Out参数必须在方法内为其赋值,方法为可以不用赋值

Ref参数:

Ref参数的主要作用:主要侧重于将值带入方法中,再带出来。

Ref参数在方法外必须要赋值。
回复 使用道具 举报
out参数
主要作用,就是返回多个参数,
out参数 必须在方法内为其赋值,方法为可以不用赋值

ref参数
ref参数在方法外必须要赋值
主要作用,主要侧重于将值传入方法中,在带出来
回复 使用道具 举报
ref是向方法中传入值,所以在调用方法前必须对ref修饰的参数进初始化!
out是从方法中传出值,所以在外部在调用方法前不用为out修饰的参数赋值,因为,就算是事先赋了值,方法里面的out参数也不会接受外部传来的值,所以,方法内部的out参数,在离开该方法之前必须对它进行赋值!
回复 使用道具 举报
首先:两者都是按地址传递的,使用后都将改变原来参数的数值。

其次:rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,rel是有进有出,out是只出不进。





ref(C# 参考)
ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。

例如:

class RefExample

{

    static void Method(ref int i)

    {

        i = 44;

    }

    static void Main()

    {

        int val = 0;

        Method(ref val);

        // val is now 44

    }

}

传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。

尽管 ref 和 out 在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:

class CS0663_Example

{

    // Compiler error CS0663: "cannot define overloaded

    // methods that differ only on ref and out".

    public void SampleMethod(ref int i) { }

    public void SampleMethod(out int i) { }

}

但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载,如下例所示:

class RefOutOverloadExample

{

    public void SampleMethod(int i) { }

    public void SampleMethod(ref int i) { }

}



out(C# 参考)
out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。

例如:

class OutExample

{

    static void Method(out int i)

    {

        i = 44;

    }

    static void Main()

    {

        int value;

        Method(out value);

        // value is now 44

    }

}

尽管作为 out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。



ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:

class CS0663_Example

{

    // Compiler error CS0663: "Cannot define overloaded

    // methods that differ only on ref and out".

    public void SampleMethod(out int i) { }

    public void SampleMethod(ref int i) { }

}



但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:

class RefOutOverloadExample

{

    public void SampleMethod(int i) { }

    public void SampleMethod(out int i) { }

}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马