我有一个基类,它有一个将文件移动到适当文件夹的方法。有许多不同的文件有许多不同的命名方案。每个文件的移动和文件夹创建都是相同的,但由于文件名不同,确定日期也不同。我想这样做:
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'关键字,这将隐藏原始实现并允许派生实现接管。这不是正在发生的事情。显然我在这种情况下不理解新的目的,那里的任何人都可以帮助我理解这个吗?
感谢。
答案 0 :(得分:5)
将方法标记为虚拟,然后在派生类中覆盖它们。 New允许您更改项的签名,因此如果基类具有名为void DoWork()的方法,则可以使用new关键字在派生类中声明int DoWork()。这解决了隐式调用,但您仍然可以显式调用基类方法。
使用虚拟(基础)和覆盖(派生)
答案 1 :(得分:4)
你真正想要的是在基类中创建基类的方法virtual
然后override
。
public class BaseClass {
public virtual int Foo() {
return 1;
}
}
public class SubClass : BaseClass {
public override int Foo() {
return 42;
}
}
答案 2 :(得分: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();
}
答案 3 :(得分:1)
在这种情况下,您需要在基类中使用Virtual
,在派生类中使用Override
。如果你这样做,它的工作方式就像你期望的那样使用`new'。
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()";
}
}