1

我有一个基类,它具有将文件移动到适当文件夹的方法。有许多不同的文件具有许多不同的命名方案。每个文件的移动和文件夹创建都是相同的,但是由于文件名不同,确定日期是不同的。我正在尝试这样做:

public class FileBase
{
   protected FileInfo _source;

   protected string GetMonth()
   {
       // 2/3 Files have the Month in this location
       // So I want this to be used unless a derived class
       // redefines this method.
       return _source.Name.Substring(Source.Name.Length - 15, 2);
   }

   public void MoveFileToProcessedFolder()
   {
      MoveFileToFolder(Properties.Settings.Default.processedFolder + GetMonth);
   }

   private void MoveFileToFolder(string destination)
   {
       ....
   }
}

public class FooFile : FileBase
{
    protected new string GetMonth()
    {
        return _source.Name.Substring(Source.Name.Length - 9, 2);
    }
}

public class Program
{
    FooFile x = new FooFile("c:\Some\File\Location_20110308.txt");
    x.MoveFileToProcessedFolder();
}

问题是此代码导致在“MoveFileToProcessedFolder”方法中调用“GetMonth”的基类版本。我认为使用“new”关键字,这将隐藏原始实现并允许派生实现接管。这不是正在发生的事情。显然我不理解 new 在这种情况下的目的,那里的任何人都可以帮助我理解这一点吗?

谢谢。

4

4 回答 4

5

将方法标记为虚拟,然后在派生类中覆盖它们。New 允许您更改项目的签名,因此如果基类具有名为 void DoWork() 的方法,您可以使用 new 关键字在派生类中声明 int DoWork()。这解决了隐式调用,但您仍然可以显式调用基类方法。

使用虚拟(基础)和覆盖(派生)

于 2011-03-08T18:07:33.000 回答
4

您真正想要的是制作基类的方法virtual,然后override在子类中制作。

public class BaseClass {
    public virtual int Foo() {
        return 1;
    }
}

public class SubClass : BaseClass {
    public override int Foo() {
        return 42;
    }
}
于 2011-03-08T18:08:07.463 回答
3

只有在被隐藏方法的类型直接引用时,它才会隐藏。但是,由于您是从基类调用实现,因此它会推迟到那里定义的方法。

在您的情况下,听起来您想要虚拟实现而不是方法隐藏。

public class FileBase
{
   protected FileInfo _source;

   protected virtual string GetMonth()
   {
       // 2/3 Files have the Month in this location
       // So I want this to be used unless a derived class
       // redefines this method.
       return _source.Name.Substring(Source.Name.Length - 15, 2);
   }

   public void MoveFileToProcessedFolder()
   {
      MoveFileToFolder(Properties.Settings.Default.processedFolder + GetMonth());
   }

   private void MoveFileToFolder(string destination)
   {
       ....
   }
}

public class FooFile : FileBase
{
    protected override string GetMonth()
    {
        return _source.Name.Substring(Source.Name.Length - 9, 2);
    }
}

public class Program
{
    FooFile x = new FooFile("c:\Some\File\Location_20110308.txt");
    x.MoveFileToProcessedFolder();
}
于 2011-03-08T18:09:22.953 回答
1

在这种情况下,您需要Virtual在基类和Override派生类中使用。如果您执行以下操作,它会按照您期望使用“新”的方式工作。

class Program
    {
        static void Main(string[] args)
        {
            FileBase fb = new FileBase();
            Console.WriteLine(fb.GetMonth());

            FooFile ff = new FooFile();
            Console.WriteLine(ff.GetMonth());

            Console.ReadLine();

        }
    }

   public class FileBase
   {
       public string GetMonth()
       {
           return "FileBase::GetMonth()";
       }

    }

    public class FooFile : FileBase
    {
        public new string GetMonth() // Hides the base method
       {
           return "FooFile::GetMonth()";
       }
    }
于 2011-03-08T18:35:21.827 回答