下面的代码是用Vb.Net编写的,但我也接受了C#解决方案。
我有这些课程:
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
在CommandlineParameterCollection
我添加了一个通用Add
方法:
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
然后我以这种方式使用它:
Dim cmds As New CommandlineParameterCollection
With cmds
.Add(Of String)(Param1) ' CommandlineParameter(Of String)
.Add(Of Boolean)(Param2) ' CommandlineParameter(Of Boolean)
End With
现在,问题是,当我调用Indexer时,它返回CommandlineParameter
(CommandlineParameter(Of Object)
)然后我需要在源代码周围指定附加的直播来指定它是什么类型,一个例子:
Console.WriteLine(CStr(cmds(Param1).Value))
Console.WriteLine(Cbool(cmds(Param2).Value))
然后为了避免这种情况,我尝试指定一个泛型类型的索引器,但我发现.Net不支持这个。
所以到目前为止我有这个索引器:
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
有什么解决方案可以避免额外的强制转换并返回我想要的类型的值?
我将澄清CommandlineParameter
(CommandlineParameter(Of Object)
)类根本没有必要,如果解决方案暗示删除它,那么我可以删除它,因为我设计它只是为了使用更友好那个对象。
答案 0 :(得分:1)
由于Collection<T>
假定每个项目都具有相同的T
,因此您无法将CommandlineParameter<string>
和CommandlineParameter<bool>
存储在同一Collection<T>
中。
IMO,你能做的最好是模仿这样的收集行为:
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];
}
}