.NET框架错误?覆盖方法的参数不会改变

时间:2016-01-14 08:04:25

标签: c# .net

以下代码无法正常工作:

using System;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass cl = new MyClass();
            cl.doSomething();
        }
    }

    public class MyClass : BaseClass
    {
        protected override void doSelect(DataTable dt)
        {
            dt = null;
        }

        public void doSomething()
        {
            base.Fill();
        }
    }

    public class BaseClass
    {
        private DataTable dtMain = null;

        protected virtual void doSelect(DataTable dt)
        {
        }

        protected void Fill()
        {
            dtMain = new DataTable();
            this.doSelect(dtMain);
            if (dtMain == null)
                Console.WriteLine("as I would expect");
            else
                Console.WriteLine("why not changed???");
        }
    }
}   

我用其他引用类型测试了它,但行为相同。这是一个框架错误吗?当我使用ref关键字时,它按预期工作:

protected virtual void doSelect(ref DataTable dt)
{
} and so on

很高兴我有人可以帮助我!

4 个答案:

答案 0 :(得分:1)

考虑以下

class Program
{
  static void Main(string[] args)
  {
    var pr = new Program();
    f(pr);
    if (pr == null)
      Console.WriteLine("Can't happen");
    else
      Console.WriteLine("Always happen");

  }

  public static void f(Program prog)
  {
    prog = null;
  }
}

pr对某些内存地址的变量引用,比如说0x111111
当您拨打f方法时,实际发生的是,prog变量被指定为与pr ei 0x111111相同的值。
当您将null分配给prog变量,它会使prog变量指向null但不会pr变量内容,而0x111111中存储的内容也不会改变。因此,pr变量仍引用0x111111内存地址。你的情况也是如此。

答案 1 :(得分:0)

使用ref关键字时,参数将按值传递。如果您更改值(即引用)以引用其他内容(此处为null),则不会在调用者方面反映出来。

这与您使用virtualoverride无关。

此处ref的替代方法是返回新值(而不是返回void),如:

protected virtual DataTable doSelect(DataTable dt)
{ /* ... */ }

确保您的方法名称反映了该方法的作用。

答案 2 :(得分:0)

doSelect()null分配给dt时,它只会更改其堆栈帧中指针的值。但是,Fill()拥有自己的堆栈框架,并拥有dtMain自己的“副本”。 doSelect()未更改此值。

通过ref传递值意味着将指针传递给调用者(Fill())堆栈框架内的值。

答案 3 :(得分:0)

这不是一个错误。 这是预期的行为。 除非您使用ref关键字,否则您将按值传递,因此方法“客户端”侧的值不会更改。 阅读ref关键字的MS参考:

https://msdn.microsoft.com/en-us/library/14akc2c7.aspx