C# 方法隐藏

发布于 2024-10-21 01:17:30 字数 1079 浏览 8 评论 0原文

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

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 的目的,有人可以帮助我理解这一点吗?

谢谢。

I have a base class which has a method for moving files to appropriate folders. There are many different files with many different naming schemes. The moving and folder creation is the same for every file, but determining the date is different because of the differing file names. I am trying to do this:

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

The problem is that this code results in the base class version of 'GetMonth' being invoked inside the 'MoveFileToProcessedFolder' method. I thought that with the 'new' keyword, this would hide the original implementation and allow the derived implementation to take over. This is not what is happening. Obviously I'm not understanding the purpose of new in this case, can anyone out there help me understand this?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ㄖ落Θ余辉 2024-10-28 01:17:31

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

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

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

It will only hide when referenced directly by the type that is hiding the method. But since you are calling the implementation from the base class it is deferring to the method defined there.

In your case it sounds like you want virtual implementations rather then method hiding.

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();
}
娇妻 2024-10-28 01:17:31

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

In this case you need to use Virtual in the base class and Override in the derived class. It works the way you are expecting using `new' if you do as below.

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()";
       }
    }
饮惑 2024-10-28 01:17:30

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

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

mark the methods as virtual then override them in your derived classes. New allows you to change the signature of the item so if base class has method named void DoWork() you can declare int DoWork() in your derived class by using new keyword. This solves the implicit calls but you can still explicitly call the base class method.

Use virtual (base) and override (derived)

绝影如岚 2024-10-28 01:17:30

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

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

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

What you really want is to make the base class's method virtual and then override it in the subclass.

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

public class SubClass : BaseClass {
    public override int Foo() {
        return 42;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文