Подтвердить что ты не робот

ConfigurationElementCollection и Linq

Я написал несколько коллекций настраиваемых конфигураций, элементов и т.д. Теперь я хотел бы сделать простой оператор Linq:

ServerDetails servers = ConfigurationManager.GetSection("serverDetails") as ServerDetails;
var server = from s in servers
             where s.Name == serverName
             select s;

Я получаю сообщение об ошибке:

Не удалось найти реализацию шаблона запроса для типа источника 'MyNamespace.ServerDetails'. "Где" не найдено.

ServerElement имеет два свойства:

public class ServerElement : ConfigurationElement
{
    [ConfigurationProperty("ip")]
    public string IP
    {
        get { return (string)base["ip"]; }
        set { base["ip"] = value; }
    }

    [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return (string)base["name"]; }
        set { base["name"] = value; }
    }
}

ServerDetails

public sealed class ServerDetails : ConfigurationSection
{
    [ConfigurationProperty("ServerCollection")]
    [ConfigurationCollection(typeof(ServerCollection), AddItemName = "add")]
    public ServerCollection ServerCollection
    {
        get { return this["ServerCollection"] as ServerCollection; }
    }
}

ServerCollection

public sealed class ServerCollection : ConfigurationElementCollection
{
    public void Add(ServerElement ServerElement)
    {
        this.BaseAdd(ServerElement);
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new ServerElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((ServerElement)element).Name;
    }
}

Я что-то упустил? Нужно ли добавлять что-то, чтобы я мог использовать Linq с настраиваемым элементом конфигурации?

Кстати, у меня есть using System.Linq;, определяемый как я использую его else где внутри одного класса.

4b9b3361

Ответ 1

Хорошо, учитывая, что все это слабо набрано, вам нужно либо явно вызвать Cast<>, либо OfType<>, либо указать явный тип переменной диапазона. Вам также нужно указать свойство ServerCollection на ServerDetails. Например:

ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
             where s.Name == serverName
             select s;

Ответ 2

Используя Brian Gideon простой пример доходности возврата в его IEnumerable <T> реализация, я смог перечислить мой ConfigurationElementCollection.

Он будет выглядеть примерно так (используя оригинальный вопрос):

public sealed class ServerCollection : ConfigurationElementCollection,
    IEnumerable<ServerElement>
{
    ...

    public new IEnumerator<ServerElement> GetEnumerator()
    {
        foreach (var key in this.BaseGetAllKeys())
        {
            yield return (ServerElement)BaseGet(key);
        }
    }
}

Пока я НЕ получал ошибку:

Не удалось найти реализацию шаблона запроса для типа источника "MyNamespace.ServerDetails". 'Где' не найдено

... Мне не удалось выполнить итерацию по моему ConfigurationElementCollection с помощью LINQ. Это решение устранило мою проблему, чтобы я мог использовать LINQ для итерации по моей коллекции.