-1

I created a class CFileInfo which inherits from the abstract FileSystemInfo class. My constructor assigns a new FileInfo object to a class-wide variable.

3 members must be overridden (Name, Exists, Delete).

However, other members are not declared Overridable in the base class, for instance CreationTime. But since the abstract class doesn't contain objects anyway, I should simply be able to overload this property, or am I mistaking here? I did this, and also for the readonly Name property.

Public Class CFileInfo
    Inherits FileSystemInfo

    Private goFile As FileInfo

    Public Sub New(ByVal sFileName As String)
        goFile = New FileInfo(sFileName)
    End Sub

    Public Overrides ReadOnly Property Exists As Boolean    'Mustoverride member.
        Get
            Return goFile.Exists
        End Get
    End Property

    Public Overrides ReadOnly Property Name As String       'Mustoverride member.
        Get
            Return goFile.Name
        End Get
    End Property

    Public Overrides Sub Delete()                           'Mustoverride member.
        goFile.Delete()
    End Sub

    Public Overloads ReadOnly Property FullName As String   'Works as intended.
        Get
            Return goFile.FullName
        End Get
    End Property

    Public Overloads Property CreationTime As Date
        Get                                                 'Does not work. Why?
            Return goFile.CreationTime
        End Get
        Set(oValue As Date)
            goFile.CreationTime = oValue
        End Set
    End Property
End Class

A class CMultiFile inherits from above CFileInfo. In it, I create a physical file, based on a FileInfo object. (The resulting FileStream is kept until Finalize disposes it.)

Public Class CMultiFile
    Inherits CFileInfo

    Private goMultiFileStream As FileStream

    Public Sub New(ByVal sFileName As String)
        MyBase.New(sFileName)
        goMultiFileStream = MyBase.Create()
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
        goMultiFileStream.Dispose()
    End Sub
End Class

The class using CMultiFile (in my case a Win Form) creates an instance of CMultiFile, which does create the file as intended.

The FileInfo object should now deliver infos about the file with which it is associated, correct. Only that it does this not for all members.

Public Class FMain
    Private goMultiFile As CMultiFile

    Private Sub cButton_Click(sender As Object, e As EventArgs) Handles cButton.Click
        Dim sMultiFileName As String = "Test.mfw"
        goMultiFile = New CMultiFile(sMultiFileName)

        MsgBox(goMultiFile.FullName & " created at " &
            goMultiFile.CreationTime.ToString)
    End Sub
End Class

Why does the (overloaded) FullName property produce a valid full path value, but the (also overloaded) CreationTime property does not? (It contains #1/1/1601 01:00:00 AM#)

Setting two Stops in CFileInfo when returning the properties FullName and CreationTime unveils, that FullName is entered and consequently does return a proper value, while CreationTime is not even entered.

What causes this behaviour and how can I access all members of my CFileInfo class?

  • What's the point of inheriting from FileSystemInfo when your class essentially delegates to FileInfo? Just use FileInfo and its stream. If you want to extend it with extra methods add a method extension – Panagiotis Kanavos Apr 18 '18 at 08:48
  • 1
    BTW a FileInfo is a *file info*, not a wrapper around a stream. Streams should *not* be kept around without reason. In this case, you're creating a file and keep it open and locked for a long time. What are you trying to do with this code? Why not just create the stream itself with eg FileInfo.Create or Open? Are you trying to create a log perhaps? Or a lock file? – Panagiotis Kanavos Apr 18 '18 at 08:51

1 Answers1

2

Overloading is wrong in both cases, i.e. FullName and CreationTime. FullName is overridable so it should be declared Overrides. You don't HAVE TO override it but you CAN do so. As for CreationTime, it should be declared Shadows. Shadows behaves much like Overrides except that, if you cast an instance of your class as its base type, you'll get the base implementation. If you override a member, you get the derived implementation even if you cast as the base type.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • `Shadows` should be avoided as much as possible. Much better to use a different name, so that the user clearly sees that there are 2 properties. – H H Apr 18 '18 at 08:50
  • @HenkHolterman much better to just use FileInfo. The question's code doesn't add anything on top of FileInfo but it *does* introduce a bug because it keeps a stream open inside another class. – Panagiotis Kanavos Apr 18 '18 at 08:52
  • Yes, this is a technically correct answer to what is probably an XY question. – H H Apr 18 '18 at 08:53