The out keyword causes arguments to be passed by reference. This is similar to the ref keyword, except that ref requires that the variable be initialized before being passed. out 和 ref 的区别就是传入的参数是否已经初始化了.class OutExample { static void Method(out int i) { i = 44; } static void Main() { int value; Method(out value); // value is now 44 } }class OutExample { static int i ; static void Method(int i) { i = 44; } static void Main() {
Method(i); // value is now 44 } }这两种实现的效果都是一样的,不过定义成成员变量后,首先是资源的浪费吧
意思差不多 但是有的变量的值是不会改变的 所以只能用out
c#的变量声明 和使用 必须是 例如:int a =5; 这样a才可以被使用 如果是:int b ; b除非被赋值,否则使用他的地方有一个编译时的错误。 out 相对于ref ,out修饰的参数,可以像b一样,不用被赋值,而直接代到方法的参数中去,但在方法中,带有out修饰符的,必须首先被赋值。ref,要想a一样,必须 先被赋值才能代到方法的参数中去,要不然,有一个编译时的错误。 out同ref一样,都是有一级地址传递的,也就是,带有这两个修饰符的参数,如果被修改了原来的值,将以新的值作为他的值,
void f(ref T p1, out T p2);p1 是一个类型为 ref T 的参数,p2 是一个带有 out 修饰(Attribute)的 类型为 T 的参数.参数: 有类型, 有无修饰(Attribute).注意类型 ref T 跟 T 是不一样的. -- Don Box <.net 本质论> 学习
可以return一起搭配使用下,比较下有什么区别没
传引用void Page_Load() { int a; int b; E(out a,out b); Response.Write(a.ToString() + "|" + b.ToString());
out 和 ref 的区别就是传入的参数是否已经初始化了.class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}class OutExample
{
static int i ;
static void Method(int i)
{
i = 44;
}
static void Main()
{
Method(i);
// value is now 44
}
}这两种实现的效果都是一样的,不过定义成成员变量后,首先是资源的浪费吧
如果是:int b ; b除非被赋值,否则使用他的地方有一个编译时的错误。
out 相对于ref ,out修饰的参数,可以像b一样,不用被赋值,而直接代到方法的参数中去,但在方法中,带有out修饰符的,必须首先被赋值。ref,要想a一样,必须 先被赋值才能代到方法的参数中去,要不然,有一个编译时的错误。
out同ref一样,都是有一级地址传递的,也就是,带有这两个修饰符的参数,如果被修改了原来的值,将以新的值作为他的值,
示例代码:1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace RefDifferenceToOut
7 {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 //这里做为ref类型的参数必须初始化。ref类型参数传入未初始化变量会报错。
13 string refTestStr = string.Empty;
14
15 //作为out类型参数可以不初始化,因为out类型参数是在函数内部赋值。
16 string outTestStr = string.Empty;
17
18 Program p = new Program();
19
20 Console.WriteLine("默认空值输出:");
21 Console.WriteLine(p.UseRef(ref refTestStr));
22 Console.WriteLine(p.UseOut(out outTestStr));
23 Console.WriteLine("refTestStr:" + refTestStr);
24 Console.WriteLine("outTestStr:" + outTestStr);
25 Console.WriteLine("-------------------");
26
27 refTestStr = "1";
28 outTestStr = "2";
29
30 Console.WriteLine("从新赋值:refTestStr = \"1\";outTestStr = \"2\";");
31 Console.WriteLine(p.UseRef(ref refTestStr));
32 Console.WriteLine(p.UseOut(out outTestStr));
33 Console.WriteLine("refTestStr:" + refTestStr);
34 Console.WriteLine("outTestStr:" + outTestStr);
35 Console.WriteLine("-------------------");
36
37
38 refTestStr = "3";
39 outTestStr = "4";
40 Console.WriteLine("从新赋值:refTestStr = \"3\";outTestStr = \"4\";");
41 Console.WriteLine(p.UseRef(ref refTestStr));
42 Console.WriteLine(p.UseOut(out outTestStr));
43 Console.WriteLine("refTestStr:" + refTestStr);
44 Console.WriteLine("outTestStr:" + outTestStr);
45 Console.WriteLine("-------------------");
46
47
48 Console.WriteLine("--------params-------");
49 p.param("str_a", "2", "3", "4");
50
51
52 }
53
54 public string UseRef(ref string refTest)
55 {
56 return refTest += "rrrrrref";
57 }
58
59 public string UseOut(out string outTestStr)
60 {
61 //在这里需要给outTest从新赋值
62 outTestStr = "0";
63 outTestStr += "oooooout";
64 return outTestStr;
65 }
66
67 /// <summary>
68 /// params参数练习。
69 /// </summary>
70 /// <param name="a">同是string参数</param>
71 /// <param name="list">string 类型列表参数</param>
72 public void param(string a,params string[] list)
73 {
74 Console.WriteLine(list.ToString());
75
76 int i = 0;
77
78 Console.WriteLine(a);
79 foreach (string s in list)
80 {
81 Console.WriteLine(i++ +"_"+ s);
82 }
83 }
84 }
85 }
86
输出结果:默认空值输出:rrrrrref0ooooooutrefTestStr:rrrrrrefoutTestStr:0oooooout-------------------从新赋值:refTestStr = "1";outTestStr = "2";1rrrrrref0ooooooutrefTestStr:1rrrrrrefoutTestStr:0oooooout-------------------从新赋值:refTestStr = "3";outTestStr = "4";3rrrrrref0ooooooutrefTestStr:3rrrrrrefoutTestStr:0oooooout---------------------------params-------System.String[]str_a0_21_32_4
总结:ref和out都对函数参数采用引用传递形式——不管是值类型参数还是引用类型参数,并且定义函数和调用函数时都必须显示生命该参数为ref/out形式。两者都可以使函数传回多个结果。两者区别:两种参数类型的设计思想不同,ref的目的在于将值类型参数当作引用型参数传递到函数,是函数的输入参数,并且在函数内部的任何改变也都将影响函数外部该参数的值;而out的目的在于获取函数的返回值,是输出参数,由函数内部计算得到的值再回传到函数外部,因此必须在函数内部对该参数赋值,这将冲掉函数外部的任何赋值,使得函数外部赋值毫无意义。表现为:1、out必须在函数体内初始化,这使得在外面初始化变得没意义。也就是说,out型的参数在函数体内不能得到外面传进来的初始值。
2、ref必须在函数体外初始化。
3、两者在函数体内的任何修改都将影响到函数体外面。再增加一个例子便于消化理解 //static void SomeFunction(int[] ints, out int i)
//{
// ints[0] = 100;
// i = 100;
//} //public static int Main()
//{
// int i = 0;
// int[] ints = { 0, 1, 2, 4, 8 };
// // Display the original values
// Console.WriteLine("i = " + i);
// Console.WriteLine("ints[0] = " + ints[0]);
// Console.WriteLine("Calling SomeFunction..."); // // After this method returns, ints will be changed,
// // but i will not
// SomeFunction(ints,out i);
// Console.WriteLine("i = " + i);
// Console.WriteLine("ints[0] = " + ints[0]);
// return 0;
//}
输出结果请自行测试
-- Don Box <.net 本质论> 学习
{
int a;
int b;
E(out a,out b); Response.Write(a.ToString() + "|" + b.ToString());
}void E(out int a,out int b)
{
a = 1;
b = 4;
}
----------
描述有错...out参数可以不经初始化
static void ff(ref Stream p1, out Stream p2, Stream p3, bool p4)
{
p2 = null;
} static void Main()
{
Type type = typeof(Program);
MethodInfo mi = type.GetMethod("ff", BindingFlags.Static | BindingFlags.NonPublic);
ParameterInfo[] pis = mi.GetParameters();
Type pt = null;
bool isout = false;
foreach (ParameterInfo pi in pis)
{
Trace.WriteLine(string.Format("参数: {0}", pi.Name));
Trace.WriteLine(string.Format("类型: {0}", pi.ParameterType.ToString()));
Trace.WriteLine(string.Format("类型 {0} {1} byRef 的", pi.ParameterType.ToString(), pi.ParameterType.IsByRef ? "是" : "不是"));
Trace.WriteLine(string.Format("isout:{0}", pi.IsOut.ToString()));
}
}
参数: p1
类型: System.IO.Stream&
类型 System.IO.Stream& 是 byRef 的
isout:False
参数: p2
类型: System.IO.Stream&
类型 System.IO.Stream& 是 byRef 的
isout:True
参数: p3
类型: System.IO.Stream
类型 System.IO.Stream 不是 byRef 的
isout:False
参数: p4
类型: System.Boolean
类型 System.Boolean 不是 byRef 的
isout:False
参数: p5
类型: System.Boolean&
类型 System.Boolean& 是 byRef 的
isout:False
参数: p6
类型: System.Boolean&
类型 System.Boolean& 是 byRef 的
isout:True
{
p2 = null;
p6 = false;
}
如果是值类型,这是传值,只会改变值副本的值,值本身不会变。
out有点像指针的意思。