我试图改进我为管理INI文件而编写的旧类,该类包含3个子类(File
,Key
,{{1分离和组织过程(一般来说是proc的过程,用于管理键/值的过程,以及用于管理段名的过程)。
嗯,我遇到的问题是,在旧班级中所有成员都被共享(道具/变量/对象/方法)并且明显可能导致分离,然后我想尝试完善其可见性成员,还有我被困的地方。
Class的当前用法是这样的:
Section
我想要的用法应该是这样的:
INIFileManager.FilePath = "ini filepath"
dim iniexist as boolean = INIFileManager.File.Exist
以下是此示例的相关代码,我被卡在dim ini as new inifilemanager("ini filepath", textencoding)
dim iniexist as boolean = ini.file.exist
dim another_ini as new inifilemanager("another ini filepath without any kind of conflict with the first instance", textencoding)
dim another_iniexist as boolean = another_ini.file.exist
类的Exist
方法上,因为我无法访问File
变量这是在顶级课程,因为我没有设置该变量,而FilePath
方法都像我Exist
那样在我的旧班级版本上...
......那我怎么能改善这个呢?
注意:请保留其他2个子类应该有一个名为Shared
的方法和其他名称相同的方法,例如" Exist
",不仅在[Get]
班级(我不知道这可能是一个可能需要更多修饰的问题)。
File
答案 0 :(得分:1)
我认为问题的一部分是你透露而不是通过类处理层次结构的太多细节。另一部分是坚持1980年代的16位Windows技术,当时有更强大的机制。
您有4个类(INIManager,File,Section,Key)来管理2位信息(Key和Value)。由于INIManager只是“容纳”其他人,因此他可以与File结合使用 - 特别是因为没有很多文件级操作。你可能甚至不需要[章节]。那些只存在,所以你可以存储类似项目的重复属性,如:
[MainDB]
Path =
File =
Foo =
[Report DB]
Path =
File =
Foo =
这些旨在以一种方式提供INItialization值,您可以通过一系列字符串循环,如FILE1,FILE2 ......并在循环中读取多个部分。对于一组简单的设置,只需使用一个[Default]部分来简化类及其使用。然后,您只需要使用IniManager和Keys。有目的地暴露底层层次结构并不适用于可用性,IMO。
为了做你想做的事,你需要INIManager
上的SECTIONS属性,它暴露了与部分相关的东西。为了支持这一点,您需要INISection
类(主要是章节的方法)和INISectionS
集合类。 (有些评论让我猜测你想要一直加载所有部分及所有密钥,以便删除它们等等。)
如果您真的想要Sections().Keys().Method
之类的内容,则必须在Key
上添加Keys collection class
课程和IniSection
。这将使总计达到5个班级来管理2个信息。当然,它可以用一半的代码和一个类来完成。大多数额外的绒毛都是以你提到的方式暴露内部工作。你也可以和Public vs Friend一起玩,以防止暴露你不想要的东西。
我在代码中没有任何东西来做PInvokes;这个问题涉及阶级建设而不是INI管理。大多数方法都是空的,只是为了看看它们如何最终为穷人用户而存在。
Public Class INIManager
' all the gory PInvokes go here
Friend cfgFile As String
Public Property INIExists As Boolean
' this is the bit you seemed to be missing
' A Collection property exposed at the IniMgr level
' containing a collection of Sections. Like matryoshka dolls, inside
' each is a collection of Keys and Values
Public Property Sections As IniSections
' no reason for INI mgr to even exist without a file
Public Sub New(iniFile As String)
cfgFile = iniFile
_INIExists = System.IO.File.Exists(cfgFile)
_Sections = New IniSections(cfgFile)
End Sub
' only worthwhile thing I can think of that a "File"
' class would ever do.
Public Sub RemoveFile()
End Sub
Public Sub Save()
' i think you need to delete the file first so any
' deleted sections disappear. of course sections the code
' does ask for doesnt do any harm either
' iterate IniSections to call a Save there,
' which iterates the keys one by one to save them
Sections.Save(cfgFile)
End Sub
' ****** INISections Class Collection
Public Class IniSections
'Inherits Collection(Of IniSection)
Private Items As Collection(Of IniSection)
Private cfgFile As String
Friend Sub New(file As String)
cfgFile = file
' I am assuming from some comments that you are probably
' loading the entire file to manage it. for that:
If System.IO.File.Exists(cfgFile) Then
' load from GetPrivateProfileSectionNames into the collection
' mybase.Items.Add(section_name)...then
For Each s As IniSection In Items
s.LoadKeyValues(cfgFile)
Next
End If
End Sub
' FRIEND!
Friend Sub Save(cfgfile As String)
For Each s As IniSection In Items
' instruct each section to write the kvps
s.Save(cfgfile)
Next
End Sub
' I dont know why an empty accessor is showing up in Intellisense
Default Public ReadOnly Property Item(name As String) As IniSection
Get
If IndexOfSection(name) = -1 Then
Items.Add(New IniSection(name))
End If
Return Items(IndexOfSection(name))
End Get
End Property
' add a section
Public Function Add(name As String) As IniSection
Dim sec As New IniSection(name)
Items.Add(sec)
Return sec
End Function
' remove a section
Public Sub Remove(name As String)
Items.RemoveAt(IndexOfSection(name))
' the only real way to remove a section is to rewrite the file!
' so to support this method we have to load all sections and all keys
' all the time even if we dont need them so that we can write the
' out the whole file omitting removed keys and sections.
'
' Seriously sir, this kind of junk went to the dustbin with Rubik's Cubes
End Sub
Public Function Exists(secName As String)
Return IndexOfSection(secName) <> -1
End Function
Private Function IndexOfSection(name As String) As Integer
For n As Integer = 0 To Items.Count - 1
' s/b ToLowerInvariant - that makes the screen scroll
If Items(n).SectionName.ToLower = name.ToLower Then
Return n
End If
Next
Return -1
End Function
End Class
End Class
' ************** INISection item class
Public Class IniSection
' mostly methods go here for sections,
' but is the "host" for the keys collections
Private myKeys As Dictionary(Of String, String)
' for a .Keys collection (WHY would the calling code WANT to
' mess with the whole collection???), change to add a Key Class
' and Keys Collection
' interface for Keys
Public Property Keys(name As String) As String
Get
If myKeys.ContainsKey(name) Then
Return myKeys(name)
Else
Return ""
End If
End Get
Set(value As String)
If myKeys.ContainsKey(value) Then
myKeys(value) = value
Else
myKeys.Add(value, value)
End If
End Set
End Property
Public Property SectionName As String
Public Sub New(name As String)
SectionName = name
myKeys = New Dictionary(Of String, String)
End Sub
Public Sub RemoveKey(name As String)
If myKeys.ContainsKey(name) Then
myKeys.Remove(name)
End If
End Sub
Friend Sub Save(inifile As String)
' iterate keys writitng the kvps to the ini
End Sub
' note FRIEND called by the INISection class not the user
Friend Function LoadKeyValues(inifile As String) As Integer
' presumably call GetPrivateProfileSection
' for this SectionName and parse it to
' get the current key=value pairs into myKeys
Return myKeys.Count
End Function
End Class
示例语法:
ini = New INIManager("C:\Temp\Ziggy.INI")
Dim foo As String = ini.Sections("foo").Keys("bar")
ini.Sections("ziggy").Keys("foo") = "zoey"
ini.Sections("ziggy").RemoveKey("zacky")
这些在语法上不匹配,因为我没有创建Key类和Keys集合类(2个信息的5个类是疯狂的)。要更改它以便setter匹配,请删除Keys访问者并添加.ReadKey()
和SetKey
,以使其在语法上匹配并将密钥集合保持在内部。你最终会得到:
ini.Sections("ziggy").RemoveKey("zacky")
ini.Sections("ziggy").ReadKey("ziggy")
ini.Sections("ziggy").SetKey(keyName, "zoey")
至少它们符合语法
ini.Sections.Add("ziggy")
ini.Sections.Remove("zoey")
If ini.Sections.Exists("zacky") Then
Console.Beep()
End If
' causes a cascade from INI -> Sections -> keys to save
ini.Save()