ještě bych se k tomu vrátil. Pan Linhart tvrdí, že požadovaná funkce není ve Frameworku implicitně dostupná, proto nezbývá, než si ji doplnit vlastními silami. Záleží samozřejmě na tom jak konkrétně s danou funkcí pracujete, kde berete vstupní data (velikost souboru), či jak jinak s tím vším pracujete. Trochu jsem si s tím hrál (protože Vámi popisované využití považuji za celkem časté), a spíše pro inspiraci přidávám jednu z mnoh amožností řešení. Pokud mne nebude zajímat nějaké obecné řešení (obecný vstup jako parametr) a spíše bych se zaměřil na funkcionalitu takovou, kdy pracuji s informacemi o souborech uložených ve formátu system.IO.Fileinfo, pak bych postupoval nejspíš cestou rozšíření funkcionality této již existující třídy. Bohužel, jako na potvoru, třída fileinfo je definována jako Noninheritable, tedy nemůžu si ji jednoduše zdědit a doplnit dle potřeby. Naštěstí ale na tomto Webu je k nalezení mnoho užitečných informací a rad i pro nás - úplné začátečníky. Již nějakou dobu zde visí odkaz na nedávno vyšedší knihu "Inovace v jazyce Visual Basic 2008" a v této knize je popsáno několik zajímavých drobností a jednou z nich jsou i tzv. rozšiřující metody. No a ty jsou pro tento účel jako stvořené. Takže pokud pro svůj projekt používáte VS 2008, můžete zvážit, nebyl-li by pro Vás zajímavým i následující postup. Do projektu si přidejte modul a do tohoto modulu si vložte požadovanou metodu, kterou byste chtěl doplnit funkcionalitu vybrané třídy. Mohlo by to vypadat třeba takhle:
Imports System.Runtime.CompilerServices
Imports System.IO
Module Module1
''' <summary>
''' Rozšiřující funkce třídy FileInfo.
''' Můžeme ji dále používat jako každou jinou funkci třídy FileInfo
''' </summary>
''' <param name="format">Můžeme specifikovat požadovaný formát číselné hodnoty,
''' pokud nespecifikujeme, dosadí se předdefinovaný</param>
''' <returns>Vrací textové vyjádření velikosti souboru vč. odpovídající jednotky</returns>
''' <remarks></remarks>
<Extension()> Public Function ToSignedString(ByVal PopisSouboru As FileInfo, Optional ByVal format As String = "#0.##") As String
Dim text As String = ""
Select Case PopisSouboru.Length
Case Is < 1024
text = PopisSouboru.Length.ToString(format) & " B"
Case Is < 1024 ^ 2
text = (PopisSouboru.Length / 1024).ToString(format) & " kB"
Case Is < 1024 ^ 3
text = (PopisSouboru.Length / 1024 ^ 2).ToString(format) & " MB"
Case Else
text = (PopisSouboru.Length / 1024 ^ 3).ToString(format) & " GB"
End Select
Return text
End Function
End Module
No a krása tohoto řešení je ve skutečnosti, že tato metoda, ač stojí zcela osamocena někde v modulu, se Vám začlení do třídy, která je definována jeko její první parametr, takže již dále prakticky nepoznáte (při práci s danou třídou), pracujete-li s metodami původními, nebo vlastními. Jasné to je z jednoduchého testovacího příkladu (na form1 přidat OpenFileDialog, 1x tlačítko a 3x label):
Imports System.IO
Public Class Form1
' pouze pro testovací a prezentační účely
' ukazuje použití rozšiřující metody
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim InfoOSouboru As FileInfo
' vybereme nějaký soubor
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
'načteme informace o tomto souboru
InfoOSouboru = New FileInfo(Me.OpenFileDialog1.FileName)
Me.Label1.Text = InfoOSouboru.Name ' kontrolní výpis jména souboru
Me.Label2.Text = InfoOSouboru.Length ' výpis hodnoty "standardní" metody třídy FileInfo
Me.Label3.Text = InfoOSouboru.ToSignedString() ' výpis hodnoty "rozšiřující" metody
End If
End Sub
End Class
Je to jistě jenom jedno z velice mnoha možných řešení, ale celkem se mi líbí pro jeho jednoduchost a hlavně pak i snadnost následujícího použití. Jinak jsem celou Vaši funkcionalitu vrazil do jedné metody, která sice možná není natolik efektní jako ta Vaše (nevyužívám rekurzi), ale měla by plnit stejný účel - určitě by se pro daný účel dala zapracovat i ta Vaše metoda získání výsledku.
|