Reputation: 20464
The code below is written in Vb.Net but I accept a C# solution too.
I have these classes:
CommandlineParameter(Of T)
Class CommandlineParameter(Of T)
End Class
CommandlineParameter
Class CommandlineParameter : Inherits CommandlineParameter(Of Object)
End Class
CommandlineParameterCollection
Class CommandlineParameterCollection : Inherits Collection(Of CommandlineParameter)
End Class
In the CommandlineParameterCollection
I added a generic Add
method:
Public Shadows Sub Add(Of T)(ByVal param As CommandlineParameter(Of T))
If Me.Contains(param.Name) OrElse Me.Contains(param.ShortName) Then
Throw New ArgumentException(message:="Parameter already exists.", "param")
Else
MyBase.Add(param)
End If
End Sub
Then I use it in this way:
Dim cmds As New CommandlineParameterCollection
With cmds
.Add(Of String)(Param1) ' CommandlineParameter(Of String)
.Add(Of Boolean)(Param2) ' CommandlineParameter(Of Boolean)
End With
Now, the problem is that when I call the Indexer, it returns me a CommandlineParameter
(CommandlineParameter(Of Object)
) then I need to specify additionals directcasts around my source-code to specify what type it is, an example:
Console.WriteLine(CStr(cmds(Param1).Value))
Console.WriteLine(Cbool(cmds(Param2).Value))
Then to avoid this, I tried to specify a generic type Indexer but I discovered that .Net doesn't support this.
So by the moment I have this indexer:
Default Public Overloads Property Item(ByVal paramName As String) As CommandlineParameter
<DebuggerStepThrough>
Get
Return Me.Find(paramName)
End Get
<DebuggerStepThrough>
Set(ByVal value As CommandlineParameter)
Me(Me.IndexOf(paramName)) = value
End Set
End Property
What solution exists for this to avoid the additional casts and return a value of the type I want?
I will clarify that the CommandlineParameter
( CommandlineParameter(Of Object)
) class is not necessary at all, If a solution implies delete it then I can delete it, because I designed it just to make more friendly the usage of that object.
Upvotes: 0
Views: 105
Reputation: 37770
Since Collection<T>
assumes, that every item has the same T
, you can't store CommandlineParameter<string>
and CommandlineParameter<bool>
in the same Collection<T>
.
IMO, best you can do here is to mimic collection behavior like this:
class CommandLineParameter<T> { }
class CommandlineParameterCollection
{
// use most common type to store items in inner collection - object
private readonly List<object> inner;
public void Add<T>(CommandLineParameter<T> value)
{
inner.Add(value);
}
public void Remove<T>(CommandLineParameter<T> value)
{
inner.Remove(value);
}
public CommandLineParameter<T> GetAt<T>(int index)
{
// will throw InvalidCastException if T at given index doesn't match passed T
return (CommandLineParameter<T>)inner[index];
}
}
Upvotes: 1