-
Aug 30th, 2011, 05:14 PM
#1
[VS2010] FlagCollection Class
[C# version here]
I had the need for a project to quickly design a flexible system that can create boolean flags based on a name and allow for quickly setting/getting the value of them.
My first thought was to implement it as a Dictionary(Of String, Boolean), but I was told that this needed to be serializable, which immediately axed the Dictionary idea as that is -not- serializable [I have tested, if someone finds out otherwise, let me know], so what I decided to do is recreate Dictionary-like attributes using only a List and a Structure.
Along the way, I realized that, as it being a list, I could only access the data using a numerical index:
Code:
Dim list As New List(Of Flag)
Dim F As New Flag
F.Name = "XYZ"
F.Value = False
list.Add(F)
Console.WriteLine(list(0).Value)
That's fine and dandy, but that doesn't help me when I'm dealing with names, and calling with names, and searching with names. So, I decided to implement System.Collections.Generic.List(Of FlagCollection.Flag) which gave me some more freedom over what to do with the list.
After working around for awhile, I figured out how to overload the item property, allowing me to change how I searched for data and also what was returned, so the above code could now be transformed:
Code:
Dim list As New List(Of Flag)
Dim F As New Flag
F.Name = "XYZ"
F.Value = False
list.Add(F)
Console.WriteLine(list("XYZ"))
Both of those code snippets will produce the exact same result with this class now. I'm not sure how useful this class will be to someone, but I decided to post it up anyways; maybe someone will get some use out of it.
Enough rambling, here's the code. This was run through a translator as I originally coded this in C#:
Code:
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Namespace FlagCollection
''' <summary>
''' An implementation if a flag collection system using a Generic List from the collections namespace
''' </summary>
Public Class FlagCollection
Inherits System.Collections.Generic.List(Of FlagCollection.Flag)
''' <summary>
''' An individual structure that contains data for a flag.
''' </summary>
<Serializable()> _
Public Structure Flag
''' <summary>
''' Returns or sets the Name of this flag.
''' </summary>
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = Value
End Set
End Property
Private m_Name As String
''' <summary>
''' Returns or sets if the flag is set or not.
''' </summary>
Public Property Value() As Boolean
Get
Return m_Value
End Get
Set(ByVal value As Boolean)
m_Value = Value
End Set
End Property
Private m_Value As Boolean
End Structure
''' <summary>
''' Adds a new flag to the flag collection. The return value indicates if the flag was successfully added.
''' </summary>
''' <param name="Name">The name of the flag to add.</param>
''' <param name="Value">The value to set the flag to.</param>
Public Overloads Function Add(ByVal Name As String, ByVal Value As Boolean) As Boolean
'Use a bit of LINQ magic.
Dim currentFlags = (From _flags In Me Where _flags.Name.Equals(Name) Select _flags).ToList()
'Check
If currentFlags.Count.Equals(0) Then
Me.Add(New Flag() With { _
.Name = Name, _
.Value = Value _
})
Return True
Else
Return False
End If
End Function
''' <summary>
''' Removes a Flag from the collection. The return value indicates if the removal was
''' successful.
''' </summary>
''' <param name="Name">The name of the flag to remove.</param>
''' <returns></returns>
Public Overloads Function Remove(ByVal Name As String) As Boolean
'See if it even exists
Dim flagList = (From flag In Me Where flag.Name.Equals(Name) Select flag).ToList()
'Check
If flagList.Count.Equals(0) Then
Return False
Else
Me.Remove(flagList(0))
Return True
End If
End Function
''' <summary>
''' Checks to see if a flag exists.
''' </summary>
''' <param name="Name">The name of the flag to check.</param>
''' <returns></returns>
Public Overloads Function Exists(ByVal Name As String) As Boolean
Return (From f In Me Where f.Name.Equals(Name) Select f).ToList().Count.Equals(1)
End Function
''' <summary>
''' Returns the value of a flag.
''' </summary>
''' <param name="Name">The name of the flag to return.</param>
''' <exception cref="FlagNotFoundException">When thrown, the flag name will be passed.</exception>
''' <returns>Returns the value of the flag.</returns>
Public Function GetFlagValue(ByVal Name As String) As Boolean
'LINQ Magic
Dim flags = (From flag In Me Where flag.Name.Equals(Name) Select flag).ToList()
'Check
If flags.Count.Equals(0) Then
Throw New FlagNotFoundException(Name)
Else
Return flags(0).Value
End If
End Function
''' <summary>
''' Sets a flag with a new value.
''' </summary>
''' <param name="Name">The name of the flag to set.</param>
''' <param name="newValue">The new value of the flag.</param>
''' <exception cref="FlagNotFoundException">When thrown, the flag name will be passed.</exception>
''' <returns>A true or false indicating if the flag was set properly.</returns>
Public Function SetFlagValue(ByVal Name As String, ByVal newValue As Boolean) As Boolean
'LINQ Magic
Dim flags = (From flag In Me Where flag.Name.Equals(Name) Select flag).ToList()
'Check
If flags.Count.Equals(0) Then
Throw New FlagNotFoundException(Name)
Else
Me.Remove(Name)
Me.Add(Name, newValue)
Return True
End If
End Function
''' <summary>
''' Returns or sets the value of the given flag.
''' </summary>
''' <param name="name">The name of the flag.</param>
''' <returns></returns>
Default Public Overloads Property Item(ByVal name As String) As Boolean
Get
Return Me.GetFlagValue(name)
End Get
Set(ByVal value As Boolean)
If Not Me.Exists(name) Then
Me.Add(New Flag() With { _
.Name = name, _
.Value = If(Not Object.ReferenceEquals(value, Nothing), value, False) _
})
Else
Me.SetFlagValue(name, value)
End If
End Set
End Property
''' <summary>
''' Serializes all current flags to a byte array.
''' </summary>
''' <returns></returns>
Public Function Save() As Byte()
'Build a memory-stream
Dim ms As New System.IO.MemoryStream()
'Build the serializer
Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'Go ahead and save all the data
bf.Serialize(ms, Me)
'Now get our byte array
Dim data As Byte() = ms.ToArray()
'Close the array
ms.Close()
'Return the data
Return data
End Function
''' <summary>
''' Deserializes all data from the byte array to the flags.
''' </summary>
''' <param name="data">The data to de-serialize.</param>
Public Sub Load(ByVal data As Byte())
'Build a memory-stream
Dim ms As New System.IO.MemoryStream(data)
'Build the deserializer.
Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'Get all the data
Dim FlagData = bf.Deserialize(ms)
'close the stream
ms.Close()
'Clear our current data
Me.Clear()
'assign the data
Me.AddRange(DirectCast(FlagData, List(Of Flag)))
End Sub
End Class
''' <summary>
''' This exception is thrown when the given flag does not exist.
''' </summary>
Public Class FlagNotFoundException
Inherits System.Exception
Private _msg As String
''' <summary>
''' The name of the flag being checked.
''' </summary>
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = Value
End Set
End Property
Private m_Name As String
Public Overrides ReadOnly Property Message() As String
Get
Return _msg
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("{0}{1}{2}", Me.Message, Environment.NewLine, Me.StackTrace)
'return base.ToString();
End Function
''' <summary>
''' Creates a new FlagNotFoundException.
''' </summary>
''' <param name="FlagName">The name of the flag.</param>
Public Sub New(ByVal FlagName As String)
Me.Name = FlagName
_msg = String.Format("The flag '{0}' was not found in the collection!", FlagName)
End Sub
End Class
End Namespace
Last edited by formlesstree4; Aug 30th, 2011 at 05:21 PM.
Reason: Grammar fix
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|