public function main()
{
   DataTable dt=New DataTable();
   A(dt);
   //dt没有人和变化
}
public function A(DataTable dt)
{
...//dt会做很多变化
}
按道理,dt在A函数中的影响会直接传回main函数,但是现在怪现象出现了,我无论我在A中如何处理dt,main里的dt都不会变化,但是如果使用ref就有效。补充一点,我现在运行的生产作业系统就不用ref就可以产生作用。一模一样的代码,在本地调试却行不通。请问各位如何处理?大家是否遇到过?是不是我的VS2005的编译器选项不对?

解决方案 »

  1.   

    补充一下,我的A函数在实际部署中属于另一个DLL
      

  2.   

    这个问题,我一直也很疑惑,也没完全搞清楚,给你摘一篇文章的片段,也借此机会学习一下:引用类型按引用传递,值类型按值传递,这些都不错。
    一个引用类型,比如System.Array类,作为参数向一个方法传递时,传送的是指针,但是这两种代码是不是就意味着等效?void Test(Array a)和void Test(ref Array a)结果是并不完全等效。如果在函数内部调用构造函数新建了对象并赋予参数,则函数外的变量不会受影响;
    比如a = new ...如果只是改动该参数(一个对象)的字段,则会有影响,此时加不加ref都是等效的。
    比如a[i] = ...
      

  3.   

    其实我现在比较纳闷的是,现在的生产系统完全可以,一样的代码却在本地不行。生产系统的系统没有升级,而我的机器已经升级了,你说和补丁有关系吗?我还装了.net framewordk3.0
      

  4.   

    TO:其实我现在比较纳闷的是,现在的生产系统完全可以,一样的代码却在本地不行。生产系统的系统没有升级,而我的机器已经升级了,你说和补丁有关系吗?我还装了.net framewordk3.0
    确实比较奇怪,说不定有一定的关系...遇到这样的问题,确实比较郁闷..
      

  5.   

    我还专门回滚代码,DLL工程的属性是一致的(“不安全代码访问--被允许”)。
    尝试过,用ref就可以解决。关键,整个工程里有很多啊,难道真的要来一次重构?
      

  6.   

    传递引用 和传递 ref 引用的区别,是第一个传递指针,第二个是传递指向指针的指针,所以第一个你可以修改那个指针指向的内容,但不能修改指针本身的地址,第二个则可以修改指针地址
      

  7.   

    hdt(倦怠) :
    传递引用 和传递 ref 引用的区别,是第一个传递指针,第二个是传递指向指针的指针,所以第一个你可以修改那个指针指向的内容,但不能修改指针本身的地址,第二个则可以修改指针地址up ~PS:很到位~~
      

  8.   

    我觉得能能不用ref,尽量不要用。
    因为ref指的是同一变量,它都能改变变量的指向。void Test(Object a)和void Test(ref Object a)
    根本就不是一回事。只要这个Object的内容是可修改的,那就就用第一种形式好了
      

  9.   

    是作用域的问题
    在A函数里面如果不使用dt=new DataTable()语句,则在A中处理dt,main里的dt都会变化,
    因为main()里的dt和A里的dt是DataTable类的同一个实例,只是在A中改变了它的值,作用域在main()中没有发生变化。
    如果在A中有dt=new DataTable()语句,相当于重新定义DataTable类的新实例,此dt已非彼dt,
    dt的作用域此时只在A中有效,也就是说A中的dt根本和main里面的dt已不是同一个实例,在A里面根本就没有对main()里面的dt做任何改变。
    所以我估计是楼主在A里面使用了dt=new DataTable()语句的缘故。
      

  10.   

    在A中的任何修改不影响 main中的dt
    除非用ref
      

  11.   

    传递引用 和传递 ref 引用的区别,学过C++的话应该很好理解.
    就是指针(*)和引用(&)的区别.
    void mothod(DataTable dt) 传递的是dt变量所指向的内存空间
    void mothod(ref DataTable dt) 传递的是dt变量本身的内存地址
    所以c++中把引用变量看作是一个变量的别名.
      

  12.   

    ref 本来就是用来代替 被滥用的指针么,呵呵。我在开发asp.net web页的时候,调用web控件,没有用引用也可以修改   回复人:hdt(倦怠) ( 四星(高级)) 信誉:120  2006-12-18 11:10:51  得分:0传递引用 和传递 ref 引用的区别,是第一个传递指针,第二个是传递指向指针的指针,所以第一个你可以修改那个指针指向的内容,但不能修改指针本身的地址,第二个则可以修改指针地址这位说得不错,很赞同这种看法。 回复人:huangyj(天外飞仙的师傅) ( 二级(初级)) 信誉:98  2006-12-18 16:53:00  得分:0建议跟踪一下看看这种调试的方法也建议尝试一下了。呵呵PS:我个人认为还是作用域的问题。废话一堆,接分来了
      

  13.   

    跟踪过了,没有用。改为ref马上起作用。我就不明白,怎么会出现这种情况?郁闷中...
      

  14.   

    你的代码在同一个程序中应该没有问题吧,在不同的文件中调用这种UI控件最好用delegate,否则会出现很怪的现象,原因我也说不清楚。
      

  15.   

    public function main()
    {
    DataTable dt=New DataTable();
    dt=A(dt);
    //dt没有人和变化
    }
    public DataTable function A(DataTable dt)
    {
    ...//dt会做很多变化
    return dt;
    }
    这样看看,因为函数中的dt不会影响main中的dt,所以让他处理后重新赋值看看
      

  16.   

    @buaawjh(猪猪爱咬咬) 你基础知识不扎实啊!ref是引用参数,指向其指针(内存位置)的
    实例参数是另外开辟存储单元,当然就不会返回值。要想返回值就两种方法, 一种return,另外一种就是使用引用参数 ref或者out
      

  17.   

    A里的dt不可能会影响到main里的dt,相反main里的dt会影响到A里的dt.
    作用域之故也,除非用 ref 或 out 作为dt的传递类型,
    又或者A()的参数为空,在main外将dt设为全局变量,
    然后在A()里对dt的任何修改都会影响到main里的dt内容。
      

  18.   

    能把public DataTable A(DataTable dt)这个函数全部贴出来吗?
      

  19.   

    static void Main() 
    {
         DataTable dt = new DataTable();
         dt.Columns.Add("A");
         dt.Columns.Add("B");
         DataRow dr = dt.NewRow();
         dr["A"] = "1";
         dr["B"] = "2";
         dt.Rows.Add(dr);
         dt = A(dt);
         MessageBox.Show(dt.Rows[0][0].ToString());

    }
    private static DataTable A(DataTable dt)
    {
         dt.Rows[0][0] = "3";
         return dt;
    }我这样写,A中的改变会影响Main中的dt。
      

  20.   

    func1(refobject obj)
    {
    obj = new refobject();
    ...
    }
    func2(refobject obj)
    {
    //without obj = new refobject();
    ...
    }
    main()
    {
    refobject obj = new refobject();
    func1(obj);//will not change obj
    func2(obj);//will change obj
    func1(ref obj);//will change obj
    }
      

  21.   

    上面的代码块有错误,如果传ref参数,方法签名也要改。大意如此。
      

  22.   

    zf904210() 和scow(怡红快绿) 的想法是一样的
    我个人也是这样认为的,比较赞同
    new一个后就会产生一个新的,和调用函数中的对象脱离关系
    但是,如果lz没有new过的话,感觉就很奇怪了
    可以把你A函数的写法贴出来看看吗
      

  23.   

    cantops(劣等游民):
    public static main()
    {
       DataTable dt=New DataTable();
       Console.WriteLine(dt.columns.count);
       A(dt);
       Console.WriteLine(dt.columns.count);
    }public static void A(DataTable dt)
    {
       dt.Columns.add(new DataColumn(ddd));
    }
    --我觉得你应该好好复习一下.net的值对象和引用对象的概念
    --我建议大家不要凭空推测,有些很简单的东西,一做实验就清楚了。
      

  24.   

    private void add(ListBox l)
    {
    l.Items.Add("aaaaaaaaaaaaa");
    } private void button1_Click(object sender, System.EventArgs e)
    {
    System.Windows.Forms.ListBox l = new ListBox();
    l.Items.Add("a");
    this.listBox1.Items.Add(l.Items.Count);
    this.add(l);
    this.listBox1.Items.Add(l.Items.Count);
    }是t m d 挺怪 不用ref 也好使
      

  25.   

    private void update(string dt)
    {
    dt = "aaaaaaaaaaaaaa";
    } private void button1_Click(object sender, System.EventArgs e)
    {
    string dt = "bbbbbbbbbbbbbb";
    this.listBox1.Items.Add(dt);
    this.update(ref dt);
    this.listBox1.Items.Add(dt);
    }
    这样就非得加ref才好使,,,
      

  26.   

    那是因为你的dt是string , net下string对象机制你可以参考其他书籍。
    基本判断,是微软的原因了,生产系统代码拷贝下来执行都不行,而生产系统却好好的,否则用户早就跳了。
      

  27.   

    一直也没真正的测试一下。写代码,,ref string 倒是总用,,,ref datatable  也用,才知道可以不用的哈。。书上说的不是这样啊。。真是的
      

  28.   

    ref的语义是传引用,即对所传引用的修改可以反映到方法外面