各位大侠,小弟有一事不明,特此请教。
C#中的变量有“值类型(例如,int)”和“引用类型(例如,类)”两种,而我认为ref参数只对值类型“有影响”,而对引用参数“没有任何影响”。我这么说可能比较模糊,下面举个例子。我自己定义了一个函数:
void test(ref int i)
{
     i = 10;
}
然后在主程序中:
static void Main(string[] args)
{
     int i = 100;
     test(ref i);//调用自定义函数
     Console.WriteLine("i=" + i.ToString());
}
程序结果显示i=10,证明引用参数(ref)将函数中对i的改变带回了主函数中,这是在我意料之中的,即我所说的“引用参数对值类型参数有影响”。
但是对于引用类型(比如“类”),就不同了!因为类本身就是引用类型,所以加ref与不加ref有什么区别呢?例如,我定义了一个类:
class testclass
{
      public int i;
}
又定义了一个函数:
static void test(testclass a)//注意:这里我没用ref
{
      a.i = 10;
}
然后在主程序中:
static void Main(string[] args)
{
testclass a = new testclass();
a.i = 100;
test(a);
Console.WriteLine("a.i=" + a.i.ToString());
Console.ReadLine();
}
程序输出:a.i=10。这个结果与“加上ref”之后完全相同,所以我认为ref对像“类”之类的引用类型参数没有影响。但是我最近学习c#网络编程中的UDP部分,其中有一个ReceiveFrom函数,它的一个简单重载如下:
ReceiveFrom(byte[] data, ref EndPoint Remote)
看到这里,我就疑惑了:为什么在这里的Remote参数要写成ref参数呢?EndPoint是一个类,所以本身就是一个引用类型,那么微软的牛人们为什么要在此参数前面加上一个ref呢??
百思不得其解,特此请教,望各位指点!

解决方案 »

  1.   

    不一样的,如果是穿引用可以改变object对象本身的指针,传值只能改变指针所指向的内容参考一下测试代码//传入的不是引用
    private void test(object[] arrObj)
    {
    arrObj[0]="arrObj[0]可以改变";
    arrObj=new object[]{"arrObj可以改变"};
    }
    //传入引用
    private void test(ref object[] arrObj)
    {
    arrObj[0]="arrObj[0]可以改变";
    arrObj=new object[]{"arrObj可以改变"};
    }
    private void button1_Click(object sender, System.EventArgs e)
    {
    object[] o=new Object[]{"jinjazz"};
    test(o);
    MessageBox.Show(o[0].ToString());test(ref o);
    MessageBox.Show(o[0].ToString());
    }
      

  2.   

    楼上两位说了等于没有说。楼主问的是:EndPoint是一个类,所以本身就是一个引用类型,那么微软的牛人们为什么要在此参数前面加上一个ref呢??
      

  3.   

    这里有个class obj和struct obj本身的语言特性的问题。
    C#和C++不同,一个class obj是一个引用值,而struct obj是一个副本值。
    形如:func(class1 obj)会将obj对象的引用传入func1函数,所以在func内部可以修改obj的实际值,而func(struct strObj)只是将strObj的一个副本传入,所以strObj本身不会被修改。
    所以,对于struct 变量和系统内建数据类型如int,string等需要一个类似C++中传引用的机制来在函数内部修改传入参数实际值,ref就是这个功能。
      

  4.   

    sorry,没看清LZ问题,当顶吧
      

  5.   

    ref
    方法参数上的 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
      

  6.   

    方法中的形参不同于一般的值类型、引用类型。不带参数的默认形参是传值,输入方法的参数是COPY值,这样不影响原始数据。但如果把形参定义为ref,那就属于传址了,方法中的操作结果会修改原始数据。
      

  7.   

    http://blog.csdn.net/cwwhy/archive/2005/10/14/503785.aspx