C# C方法隐藏

C# C方法隐藏,c#,method-hiding,C#,Method Hiding,我有一个基类,它有一个将文件移动到适当文件夹的方法。有许多不同的文件具有许多不同的命名方案。每个文件的移动和文件夹创建都是相同的,但由于文件名不同,确定日期也不同。我正在尝试这样做: public class FileBase { protected FileInfo _source; protected string GetMonth() { // 2/3 Files have the Month in this location // So I

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

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允许您更改项的签名,这样,如果基类具有名为void DoWork的方法,您可以使用New关键字在派生类中声明int DoWork。这解决了隐式调用,但仍然可以显式调用基类方法


使用虚拟基并重写派生的

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


使用虚拟基和重写派生的

您真正想要的是使基类的方法虚拟,然后在子类中重写它

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

public class SubClass : BaseClass {
    public override int Foo() {
        return 42;
    }
}

您真正想要的是使基类的方法虚拟,然后在子类中重写它

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

public class SubClass : BaseClass {
    public override int Foo() {
        return 42;
    }
}

它仅在被隐藏该方法的类型直接引用时才隐藏。但是,由于您是从基类调用实现,因此它遵从在基类中定义的方法

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

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

它仅在被隐藏该方法的类型直接引用时才隐藏。但是,由于您是从基类调用实现,因此它遵从在基类中定义的方法

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

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

在这种情况下,需要在基类中使用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()";
       }
    }

在这种情况下,需要在基类中使用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()";
       }
    }

并查看什么是虚拟方法以及它们如何提供帮助。这正是它们的设计目的。看看什么是虚拟方法,以及它们如何提供帮助。这正是它们的设计目的。这听起来太疯狂了。非转义路径名暗示您可能完全错误。是的。使用foofilex=newFooFile@c:\Some\File\Location\u 20110308.txt;只需在字符串之前添加@。这只是一个简化的示例。文件名不是真实的。在实际路径中是转义和正确的。这听起来完全疯狂。非转义路径名暗示您可能完全错误。是的。使用foofilex=newFooFile@c:\Some\File\Location\u 20110308.txt;只需在字符串之前添加@。这只是一个简化的示例。文件名不是真实的。在实际的路径中是转义和正确的。哎呀,就像一个符咒!谢谢有什么原因可以解释为什么这个有效而新的无效?从描述上看,这似乎是新的应该工作,但感谢你的解决方案。啊,工作就像一个魅力!谢谢有什么原因可以解释为什么这个有效而新的无效?从描述来看,这似乎是新的工作,但感谢您的解决方案。