C # метод сокрытия - PullRequest
       28

C # метод сокрытия

1 голос
/ 08 марта 2011

У меня есть базовый класс, в котором есть метод для перемещения файлов в соответствующие папки.Есть много разных файлов с разными схемами именования.Перемещение и создание папки одинаковы для каждого файла, но определение даты отличается из-за разных имен файлов.Я пытаюсь сделать это:

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

Проблема состоит в том, что этот код приводит к тому, что версия GetMonth базового класса вызывается внутри метода MoveFileToProcessedFolder.Я подумал, что с ключевым словом «new» это скрыло бы исходную реализацию и позволило бы взять на себя производную реализацию.Это не то, что происходит.Очевидно, я не понимаю цели нового в этом случае, может кто-нибудь помочь мне понять это?

Спасибо.

Ответы [ 4 ]

5 голосов
/ 08 марта 2011

пометьте методы как виртуальные, а затем переопределите их в ваших производных классах.New позволяет вам изменить сигнатуру элемента, поэтому, если в базовом классе есть метод с именем void DoWork (), вы можете объявить int DoWork () в своем производном классе, используя ключевое слово new.Это решает неявные вызовы, но вы все равно можете явно вызывать метод базового класса.

Использовать виртуальный (базовый) и переопределить (производный)

4 голосов
/ 08 марта 2011

Что вам действительно нужно, так это сделать метод базового класса virtual и затем override в подклассе.

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

public class SubClass : BaseClass {
    public override int Foo() {
        return 42;
    }
}
3 голосов
/ 08 марта 2011

Он будет скрыт только при прямой ссылке на тип, который скрывает метод.Но поскольку вы вызываете реализацию из базового класса, она откладывается до метода, определенного там.

В вашем случае это звучит так, как будто вы хотите виртуальные реализации, а не скрытие метода.

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();
}
1 голос
/ 08 марта 2011

В этом случае вам нужно использовать 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()";
       }
    }
...