0

I've got a ConfigurationSection in my app.config which includes a list of http Endpoints (~50). Each one has an optional priority (as well as a default).

I'd like to display this list in order.

Dim Config As MyConfigSection = DirectCast(System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None).Sections("MySection"), MyConfigSection)
Dim Endpoints = MyConfigSection.InitialEndpoints

In this case InitialEndpoints is of type Endpointcollection which Inherits ConfigurationElementCollection and is just a noddy collection which is loosely typed.

The Endpoint collection happens to deal with EndpointDefinitions which in turn have a Url, Priority, etc...

I'd like to be able to do...

For Each E in Endpoints.OrderBy(function(x) x.Priority)
    ...
Next

Do I really need to create a new list/collection and transfer the objects across, casting them as I go?

Cheating and casting the collection as an IEnumerable resulted in an invalid cast (not entirely unexpected)

An alternate thought was to do something like...

Endpoints.Select(function(x) DirectCast(x, Endpointdefinition)).OrderBy(...)

But EndpointCollection isn't a list so doesn't benefit from the LINQ Select() extension. I could always implement IList but now it feels like I'm using a sledgehammer to crack a nut.

Can someone please point out the obvious way to do this? For reference, my EndpointCollection is below

<ConfigurationCollection(GetType(EndpointDefinition), AddItemName:="Endpoint")>
    Public Class EndpointCollection
        Inherits ConfigurationElementCollection

        Protected Overloads Overrides Function CreateNewElement() As ConfigurationElement
            Return New EndpointDefinition
        End Function

        Protected Overrides Function CreateNewElement(elementName As String) As ConfigurationElement
            Return New EndpointDefinition With {.Url = elementName}
        End Function

        Protected Overrides Function GetElementKey(element As ConfigurationElement) As Object
            Return DirectCast(element, EndpointDefinition).Url
        End Function

        Public Overrides ReadOnly Property CollectionType As ConfigurationElementCollectionType
            Get
                Return ConfigurationElementCollectionType.AddRemoveClearMap
            End Get
        End Property

        Public Shadows Property Item(index As Integer) As EndpointDefinition
            Get
                Return CType(BaseGet(index), EndpointDefinition)
            End Get
            Set(value As EndpointDefinition)
                If Not (BaseGet(index) Is Nothing) Then
                    BaseRemoveAt(index)
                End If
                BaseAdd(index, value)
            End Set
        End Property
    End Class
4

1 回答 1

3

你的问题是你的类实现了IEnumerable,而不是IEnumerable(Of T)

由于EndpointCollection继承ConfigurationElementCollectionConfigurationElementCollection实现IEnumerable,您可以使用OfType()扩展方法(或者Cast(),如果需要)。

因此,您应该能够执行以下操作:

Dim Endpoints = MyConfigSection.InitialEndpoints.OfType(Of Endpointdefinition).OrderBy(function(x) x.Priority)

或者

Dim Endpoints = MyConfigSection.InitialEndpoints.Cast(Of Endpointdefinition).OrderBy(function(x) x.Priority)
于 2012-08-29T10:04:41.953 回答