c#编程问题

ref和out的用法 我刚学c#学到这里我很迷惑 不知道为什么要用 好处在哪里 请哪位高手跟我举个很简单的例子说说 谢谢

参数修饰符ref,out ,params的区别:

params 关键字可以指定在参数数目可变处采用参数的方法参数。

在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。

示例
// cs_params.cs
using System;
public class MyClass
{

public static void UseParams(params int[] list)
{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine(list[i]);
Console.WriteLine();
}

public static void UseParams2(params object[] list)
{
for ( int i = 0 ; i < list.Length ; i++ )
Console.WriteLine(list[i]);
Console.WriteLine();
}

public static void Main()
{
UseParams(1, 2, 3);
UseParams2(1, 'a', "test");

int[] myarray = new int[3] {10,11,12};
UseParams(myarray);
}
}
输出
1
2
3

1
a
test

10
11
12

===============================================
方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。
若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。
不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。
属性不是变量,不能作为 out 参数传递。
如果两个方法的声明仅在 out 的使用方面不同,则会发生重载。不过,无法定义仅在 ref 和 out 方面不同的重载。例如,以下重载声明是有效的:
class MyClass
{
public void MyMethod(int i) {i = 10;}
public void MyMethod(out int i) {i = 10;}
}
而以下重载声明是无效的:
class MyClass
{
public void MyMethod(out int i) {i = 10;}
public void MyMethod(ref int i) {i = 10;}
}
有关传递数组的信息,请参见使用 ref 和 out 传递数组。
示例
// cs_out.cs
using System;
public class MyClass
{
public static int TestOut(out char i)
{
i = 'b';
return -1;
}

public static void Main()
{
char i; // variable need not be initialized
Console.WriteLine(TestOut(out i));
Console.WriteLine(i);
}
}
输出
-1
b

========================================
方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。
传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。
属性不是变量,不能作为 ref 参数传递。
如果两种方法的声明仅在它们对 ref 的使用方面不同,则将出现重载。但是,无法定义仅在 ref 和 out 方面不同的重载。例如,以下重载声明是有效的:
class MyClass
{
public void MyMethod(int i) {i = 10;}
public void MyMethod(ref int i) {i = 10;}
}
但以下重载声明是无效的:
class MyClass
{
public void MyMethod(out int i) {i = 10;}
public void MyMethod(ref int i) {i = 10;}
}
有关传递数组的信息,请参见使用 ref 和 out 传递数组。
示例
// cs_ref.cs
using System;
public class MyClass
{
public static void TestRef(ref char i)
{
// The value of i will be changed in the calling method
i = 'b';
}

public static void TestNoRef(char i)
{
// The value of i will be unchanged in the calling method
i = 'c';
}

// This method passes a variable as a ref parameter; the value of the
// variable is changed after control passes back to this method.
// The same variable is passed as a value parameter; the value of the
// variable is unchanged after control is passed back to this method.
public static void Main()
{

char i = 'a'; // variable must be initialized
TestRef(ref i); // the arg must be passed as ref
Console.WriteLine(i);
TestNoRef(i);
Console.WriteLine(i);
}
}
输出
b
b
参考资料:MSDN

参考资料:MSDN

温馨提示:答案为网友推荐,仅供参考
第1个回答  2007-07-13
这是我以前做的部分学习笔记,貌似正好可以解决你的问题,我另加了一点自己对书的翻译补充,你可以参考下。

首先要了解值类型(value type)和引用类型(refrence type)的区别。

引用类型指的是类(class),接口(interface),数组(array),或委托(delegate)类型。

值类型指的是结构(struct)或枚举(enum)类型,C#提供了一系列预定义的结构类型,称做简单类型。

简单类型就是C#中由保留字标识的类型,这些类型其实只是System名称空间中类型的别名而已。

以下是C#中简单类型的保留字和其对应实际类型。

sbyte
 System.SByte

byte
 System.Byte
 
short
 System.Int16
 
ushort
 System.UInt16
 
int
 System.Int32
 
uint
 System.UInt32
 
long
 System.Int64
 
ulong
 System.UInt64
 
char
 System.Char
 
float
 System.Single
 
double
 System.Double
 
bool
 System.Boolean
 
decimal
 System.Decimal

1、关键字ref

在C#中,值类型的函数传值默认使用的是按值传递,这就意味着当一个值类型的对象传入函数时,该函数为这个参数创建了一份属于自己的拷贝,当函数结束时,这份拷贝会被自动销毁。有时候我们需要在函数中对传入参数的本体进行修改,而不是这个参数的拷贝,这时我们就需要使用C#提供的ref关键字来实现值类型的按引用传递。以下是交换2个变量的值的例子:

class PassByRefDemon
{
    static void Main()
    {
        int a = 1, b = 2;

        // not what you want
        SwapByVal(a, b);
        System.Console.WriteLine(a + " " + b);

        // now it works!
        SwapByRef(ref a, ref b);
        System.Console.WriteLine(a + " " + b);
    }

    static void SwapByVal(int lhs, int rhs)
    {
        int tmp = lhs;
        lhs = rhs;
        rhs = tmp;
    }

    static void SwapByRef(ref int lhs, ref int rhs)
    {
        int tmp = lhs;
        lhs = rhs;
        rhs = tmp;
    }
}

可以看出只有使用了按引用传参的函数SwapByRef,Main函数中a和b的值才会被交换,否则交换的只是Swap函数中对传入参数a、b的拷贝的值而已。

2、关键字out

C#是一个强赋值检查(definite assignment)(不知道翻译地对不对),的语言,这意味着任何变量在他们被使用之前都应该被明确地初始化或赋值,以下是试图使用未初始化的变量引起的编译错误:

class UseUninitializedVariable
{
    static void Main()
    {
        int a;
        System.Console.WriteLine(a); // compile error
    }
}

而有的时候你在创建一个变量之后,你并不需要使用它的初始值,例如你需要获得系统的当前时间:

class GetSysTime1
{
    static void Main()
    {
        int theHour = 0; // seems silly
        int theMinute = 0;
        int theSecond = 0;

        GetTime(ref theHour, ref theMinute, ref theSecond);
        System.Console.WriteLine("Now is: " + theHour + ':' + theMinute + ':' + theSecond);
    }

    static void GetTime(ref int theHour, ref int theMinute, ref int theSecond)
    {
        theHour = System.DateTime.Now.Hour;
        theMinute = System.DateTime.Now.Minute;
        theSecond = System.DateTime.Now.Second;
    }
}

如果为其提供一个初值0仅仅是为了压制编译器的"Use of unassigned local variable xxx"错误,那么这种赋值多少有些无聊和愚蠢,因为你在他们被赋值之后将马上把他们按引用传递给函数GetTime以获得时间,所以这时候我们就需要C#提供的另外一个关键字来改变这种情形,使用out来克制C#的definite assignment。

class GetSysTime2
{
    static void Main()
    {
        int theHour;
        int theMinute;
        int theSecond;

        // now it's OK
        GetTime(out theHour, out theMinute, out theSecond);
        System.Console.WriteLine("Now is: " + theHour + ':' + theMinute + ':' + theSecond);
    }

    static void GetTime(out int theHour, out int theMinute, out int theSecond)
    {
        theHour = System.DateTime.Now.Hour;
        theMinute = System.DateTime.Now.Minute;
        theSecond = System.DateTime.Now.Second;
    }
}
第2个回答  2007-07-15
哎,被自己的钻研精神折服了,才发现没必要研究他们传递方式是怎样的,只需要注意.
out 参数在使用前不必初始化,使用时必须赋值初始化.其余一样的.
ref 参数在使用前必须初始化,使用时不必赋值初始化.其余一样的.

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网