2011-03-08 80 views
1

我有一个基类有一个将文件移动到适当的文件夹的方法。有许多不同的文件和许多不同的命名方案。移动和文件夹创建对于每个文件都是相同的,但由于文件名称不同,确定日期不同。我试图做到这一点:C#方法隐藏

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”方法内。我认为使用'new'关键字会隐藏原始实现并允许派生实现接管。这不是正在发生的事情。很显然,我并不了解这种情况下新的目的,有没有人能帮我理解这一点?

谢谢。

+0

这听起来完全疯了。非转义路径名称暗示您可能完全错误。 – stefan 2011-03-08 18:15:22

+0

是的。使用FooFile x = new FooFile(@“c:\ Some \ File \ Location_20110308.txt”);只需在字符串前添加@ – 2011-03-08 18:16:24

+0

这只是一个简化的示例。文件名不是真实的。在实际路径中转义并正确。 – Bitfiddler 2011-03-08 19:13:25

回答

5

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

使用虚拟(基地)和倍率(衍生)

+0

并查看哪些虚拟方法以及它们如何提供帮助。这正是他们所设计的。 – ssube 2011-03-08 18:09:19

4

你真正想要的是让基类的方法virtual然后override它的子类。

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

public class SubClass : BaseClass { 
    public override int Foo() { 
     return 42; 
    } 
} 
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(); 
} 
+0

Awsome,就像一个魅力!谢谢。任何理由为什么这个工程和新的不?从描述看来,新的应该可以工作,但感谢解决方案。 – Bitfiddler 2011-03-08 19:46:39

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()"; 
     } 
    }