值类型、摘引类型与ref关键字 有句话没看懂
值类型、引用类型与ref关键字 有句话没看懂
引用类型本身并不包含数据,仅仅维持了对数据的引用。
因此,使用ref参数,对值类型对象的作用显而易见,而对于引用类型,如需修改引用类型内部的数据,则无需使用ref关键字;否则,当被调用函数内部需要更改引用本身时,比如在函数内部重新定位对象的引用,则需要使用ref关键字。
这个是在网上看到的.
今天学习了一下,引用类型和 值类型还有REF ,他们之间的关系基本明白了,但是有这么一句话没看懂:”
否则,当被调用函数内部需要更改引用本身时,比如在函数内部重新定位对象的引用,则需要使用ref关键字“
上面这句能给举个例子吗,最好是代码的例子,易懂,谢谢了
------解决思路----------------------
额。。。就比如class A a=。。。、、、
a是引用类型的,你的方法要是更改a里面的数据的话,不必加ref。直接传a,就会更改。
如果你的方法会对a进行修改,如class A b=new class A();a=b;那就要在引用对象a前面加ref
------解决思路----------------------
------解决思路----------------------
------解决思路----------------------
说白了,就是如果你在方法里不重新new,仅仅是赋值的话,不用ref也可以的
如果需要重新new,不用ref,这个对象就跟传入的对象没有关系了,变成了一个新的对象
你需要使用ref关键字将新的引用传递回去
------解决思路----------------------
最简单的例子
比如Button a=new Button();
panel1.add(a);
我将这个Button添加到了panel里,然后a就没用了,可以继续a=new Button();指向一个新的Button,然后继续panel1.add(a);
如果你把 a=new Button();panel1.add(a);封装到一个方法里,传入Button,添加到panel上,不加ref也没有问题
如果你方法结束后,想继续用a这个变量,因为a已经在方法里重新new过,跟你传入的a指向的已经不是同一个对象了,所以直接用用不了,你需要用ref把它带出来
------解决思路----------------------
------解决思路----------------------
简单说
对于函数的参数,如果在函数内部进行,那么函数执行结束后,除了返回值,其他修改无效。
要获得修改后的值,使用ref就可以
------解决思路----------------------
ref是用在函数传递参数上,有时可以当做返回值来取。
------解决思路----------------------
值类型 在传参时,在函数中对该参数值修改后,不会影响原来的值。
加了ref后下,在函数中修改了,原参数值也会跟着变
这们子看吧
------解决思路----------------------
------解决思路----------------------
按引用类型传递引用类型
class MyInfo
{
public string MyName;//定义一个字符串类型变量存储用户姓名
public int MyAge;//定义一个整数类型变量存储用户年龄
public MyInfo(string name, int age)//创建一个带参数的构造函数
{
MyName = name;
MyAge = age;
}
public MyInfo() { }//默认构造函数
public void PrintInfo()//创建一个公有方法输出用户年龄信息
{
Console.WriteLine("{0}年龄是{1}岁", MyName, MyAge);
}
}
class Program
{
public static void SendAPersonByValue(ref MyInfo info)
{
info.MyAge = 99;//改变'info'的值
info = new MyInfo("薛豆豆", 25);//”info”现在指向了堆上的一个新对象
}
static void Main(string[] args)
{
Console.WriteLine("输出用户年龄信息:");
MyInfo fred = new MyInfo("范青林", 29);
Console.WriteLine("未改变用户信息前");
fred.PrintInfo();
SendAPersonByValue(ref fred);
Console.WriteLine("改变后的用户年龄信息:");
fred.PrintInfo();
}
}
------解决思路----------------------
比如你的手机坏了拿去修,店家给你换了零件,你拿回来的时候手机还是原来那台,但里面的零件给换了,这是一般的引用类型的传递方式。如果你的手机修不好,店家给你换了一台新的,拿来来的时候手机已经不是原来那台了,这是ref传值的方式。
参考以下代码。
------解决思路----------------------
比喻很形象
不加ref,则不管对手机做什么操作,都将原来你给他的手机还给你
而加了ref,则即使手机整个换掉了,也把最新的给你
引用类型本身并不包含数据,仅仅维持了对数据的引用。
因此,使用ref参数,对值类型对象的作用显而易见,而对于引用类型,如需修改引用类型内部的数据,则无需使用ref关键字;否则,当被调用函数内部需要更改引用本身时,比如在函数内部重新定位对象的引用,则需要使用ref关键字。
这个是在网上看到的.
今天学习了一下,引用类型和 值类型还有REF ,他们之间的关系基本明白了,但是有这么一句话没看懂:”
否则,当被调用函数内部需要更改引用本身时,比如在函数内部重新定位对象的引用,则需要使用ref关键字“
上面这句能给举个例子吗,最好是代码的例子,易懂,谢谢了
------解决思路----------------------
额。。。就比如class A a=。。。、、、
a是引用类型的,你的方法要是更改a里面的数据的话,不必加ref。直接传a,就会更改。
如果你的方法会对a进行修改,如class A b=new class A();a=b;那就要在引用对象a前面加ref
------解决思路----------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int[] a = { 1, 3, 5, 7, 9 };
f1(a);
ConsoleOut(a);
f2(ref a);
ConsoleOut(a);
}
static void f1(int[] a)
{
a = new int[] { 11, 33, 55, 77, 99 };
}
static void f2(ref int[] a)
{
a = new int[] { 2, 4, 6, 8, 10 };
}
static void ConsoleOut(int[] a)
{
for (int i = 0, l = a.Length; i < l; ++i)
{
Console.Write("{0,5}", a[i]);
}
Console.WriteLine();
}
}
}
运行结果:
1 3 5 7 9
2 4 6 8 10
请按任意键继续. . .
------解决思路----------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int[] a = { 1, 3, 5, 7, 9 };
f1(a);
ConsoleOut(a);
f2(ref a);
ConsoleOut(a);
}
static void f1(int[] a)
{
a[2] = 555;
a = new int[] { 11, 33, 55, 77, 99 };
}
static void f2(ref int[] a)
{
a[2] = 555;
a = new int[] { 2, 4, 6, 8, 10 };
}
static void ConsoleOut(int[] a)
{
for (int i = 0, l = a.Length; i < l; ++i)
{
Console.Write("{0,5}", a[i]);
}
Console.WriteLine();
}
}
}
运行结果:
1 3 555 7 9
2 4 6 8 10
请按任意键继续. . .
------解决思路----------------------
说白了,就是如果你在方法里不重新new,仅仅是赋值的话,不用ref也可以的
如果需要重新new,不用ref,这个对象就跟传入的对象没有关系了,变成了一个新的对象
你需要使用ref关键字将新的引用传递回去
------解决思路----------------------
最简单的例子
比如Button a=new Button();
panel1.add(a);
我将这个Button添加到了panel里,然后a就没用了,可以继续a=new Button();指向一个新的Button,然后继续panel1.add(a);
如果你把 a=new Button();panel1.add(a);封装到一个方法里,传入Button,添加到panel上,不加ref也没有问题
如果你方法结束后,想继续用a这个变量,因为a已经在方法里重新new过,跟你传入的a指向的已经不是同一个对象了,所以直接用用不了,你需要用ref把它带出来
------解决思路----------------------
class Program
{
private static string s1="abc";
private static string s2 = "def";
static void Fun(string s) // 被调用函数 1
{
s =s2; // 尝试在被调用函数1内部重新定位形参s的引用,不过这样是不通的
}
static void Fun2(ref string s) { // 被调用函数 2
s = s2; // 尝试在被调用函数2内部重新定位形参s的引用,这样是可行的 因为它使用了ref关键字
}
static void Main(string[] args)
{
string test=s1;
Fun(test);
Console.WriteLine("test={0}",test);
Fun2(ref test);
Console.WriteLine("test={0}", test);
Console.ReadKey();
}
}
------解决思路----------------------
简单说
对于函数的参数,如果在函数内部进行,那么函数执行结束后,除了返回值,其他修改无效。
要获得修改后的值,使用ref就可以
------解决思路----------------------
ref是用在函数传递参数上,有时可以当做返回值来取。
------解决思路----------------------
值类型 在传参时,在函数中对该参数值修改后,不会影响原来的值。
加了ref后下,在函数中修改了,原参数值也会跟着变
这们子看吧
static void F1(int s) {
s =1;
}
static void F2(ref int s) {
s = 2;
}
int x=1234;
F1(x); //执行后,x还是1234
F2(ref x) //执行后,x=2
------解决思路----------------------
public void aaa(ref classA aaa)
{
aaa.A=123;//这种有没有ref都一样
aaa = new classA();//这种有没有ref完全不一样
}
------解决思路----------------------
按引用类型传递引用类型
class MyInfo
{
public string MyName;//定义一个字符串类型变量存储用户姓名
public int MyAge;//定义一个整数类型变量存储用户年龄
public MyInfo(string name, int age)//创建一个带参数的构造函数
{
MyName = name;
MyAge = age;
}
public MyInfo() { }//默认构造函数
public void PrintInfo()//创建一个公有方法输出用户年龄信息
{
Console.WriteLine("{0}年龄是{1}岁", MyName, MyAge);
}
}
class Program
{
public static void SendAPersonByValue(ref MyInfo info)
{
info.MyAge = 99;//改变'info'的值
info = new MyInfo("薛豆豆", 25);//”info”现在指向了堆上的一个新对象
}
static void Main(string[] args)
{
Console.WriteLine("输出用户年龄信息:");
MyInfo fred = new MyInfo("范青林", 29);
Console.WriteLine("未改变用户信息前");
fred.PrintInfo();
SendAPersonByValue(ref fred);
Console.WriteLine("改变后的用户年龄信息:");
fred.PrintInfo();
}
}
------解决思路----------------------
比如你的手机坏了拿去修,店家给你换了零件,你拿回来的时候手机还是原来那台,但里面的零件给换了,这是一般的引用类型的传递方式。如果你的手机修不好,店家给你换了一台新的,拿来来的时候手机已经不是原来那台了,这是ref传值的方式。
参考以下代码。
public void Repair(Phone phone)
{
if (phone.Error == ERROR_KEYBOARD) // 更换键盘
phone.Keyboard = new Keyboard();
else if (phone.Error == ERROR_FAULT) // 手机已经永久性损坏必须更换
phone = new Phone(); // 请考虑加ref和不加的情况下,这行代码会产生什么样的作用。
...
}
------解决思路----------------------
比喻很形象
不加ref,则不管对手机做什么操作,都将原来你给他的手机还给你
而加了ref,则即使手机整个换掉了,也把最新的给你