Каков наилучший способ реализовать коллекцию свойство = значение - PullRequest
0 голосов
/ 01 сентября 2011

Я написал класс-оболочку для сторонней библиотеки, для которой необходимо задать свойства, вызвав метод Config и передав строку, отформатированную как " Property = Value "

Я хотел бы передать все свойства в одном вызове и обработать их итеративно.

Я рассмотрел следующее:

  • создание свойства / значениякласса и затем создание списка этих объектов
  • построение строки из нескольких символов " Property = Value ", разделяющих их токеном (возможно, "|")
  • Использованиехеш-таблица

Все это будет работать (и я думаю об использовании варианта 1), но есть ли лучший способ?

Немного подробнеео моем запросе:

Готовый класс будет включен в библиотеку для повторного использования в других приложениях.Хотя в настоящее время я не рассматриваю многопоточность как проблему (в наших приложениях обычно имеется только поток пользовательского интерфейса и рабочий поток), в будущем это может стать проблемой.

Сборка мусора не будетпроблема.

Доступ к произвольным индексам источника данных в настоящее время не является проблемой.

В настоящее время оптимизация не является проблемой, но важно четко определить пары ключ / значение.

Ответы [ 4 ]

1 голос
/ 01 сентября 2011

Как вы уже указали, любое из предложенных решений выполнит задачу, как вы ее описали.Это означает, что единственный рациональный способ выбрать конкретный метод - это определить ваши требования:

  • Должен ли ваш код поддерживать несколько потоков, одновременно обращающихся к источнику данных?Если это так, то использование ConcurrentDictionary, как предположил Яхья, имеет смысл.В противном случае, нет причин брать на себя дополнительные издержки и усложнять использование параллельной структуры данных.
  • Вы работаете в среде, где сбор мусора является проблемой (например, игра XNA)?В таком случае любое предложение, касающееся объединения строк, будет проблематичным.
  • Вам нужен O (1) доступ к произвольным индексам источника данных?Если так, ваш третий подход имеет смысл.С другой стороны, если все, что вы делаете - это перебираете коллекцию, то нет причин брать на себя дополнительные накладные расходы при вставке в хеш-таблицу;вместо этого используйте List<KeyValuePair<String, String>>.
  • С другой стороны, вы можете не работать в среде, где необходима описанная выше оптимизация;для вас может быть важна возможность четкого определения пар ключ / значение программно.В этом случае лучше использовать Dictionary.

Вы не можете принять обоснованное решение относительно , как реализовать функцию без полного определения , чтофункция должна сделать , и, поскольку вы этого не сделали, любой ответ, приведенный здесь, обязательно будет неполным.

Учитывая ваши разъяснения, я лично предложил бы следующее:

  • Старайтесь не делать ваш метод Config () поточно-безопасным по умолчанию в соответствии с рекомендациями MSDN:

    По умолчанию библиотеки классов не должны быть поточно-безопасными,Добавление блокировок для создания поточно-ориентированного кода снижает производительность, повышает конфликтность блокировок и создает возможность возникновения ошибок взаимоблокировок.

  • Если безопасность потока становится важной позже, сделайте этоответственность вызывающего абонента.

  • Учитывая, что у вас нет особых требований к производительности, придерживайтесь словаря, чтобы пары ключей / значений можно было легко определять и читать.

  • Для простоты и во избежание генерации большого количества ненужных строк, выполняющих конкатенации, просто передайте словарь напрямую и выполните итерации по нему.

Рассмотрите следующий пример:

var configData = new Dictionary<String, String>
configData["key1"] = "value1";
configData["key2"] = "value2";
myLibraryObject.Config(configData);

И реализация Config:

public void Config(Dictionary<String, String> values)
{
    foreach(var kvp in values)
    {
        var configString = String.Format("{0}={1}", kvp.Key, kvp.Value);
        // do whatever
    }
}
1 голос
/ 01 сентября 2011

Вы можете использовать Dictionary<string,string>, тогда элементы имеют тип KeyValuePair<string,string> (это соответствует вашей первой идее). Затем вы можете использовать myDict.Select(kvp=>string.Format("{0}={1}",kvp.Key,kvp.Value)), чтобы получить список строк с необходимым форматированием

0 голосов
/ 01 сентября 2011

Вы можете создать вспомогательный класс, который использует отражение, чтобы превратить любой класс в коллекцию Property = Value

public static class PropertyValueHelper
{
     public static IEnumerable<string> GetPropertyValues(object source)
     { 
          Type t = source.GetType();

          foreach (var property in t.GetProperties())
          {
               object value = property.GetValue(source, null);
               if (value != null)
               {
                    yield return property.Name + "=" + value.ToString();
               }
               else
               {
                    yield return property.Name + "=";  
               }
          }
     } 
}

Вам потребуется добавить дополнительную логику для обработки перечислений, индексированных свойств и т. Д.

0 голосов
/ 01 сентября 2011

Используйте, например, ConcurrentDictionary<string,string> - это поточно-ориентированный и очень быстрый, так как большинство операций реализовано без блокировки ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...