开发者

What is the best way to implement a property=value collection

开发者 https://www.devze.com 2023-04-01 01:55 出处:网络
I\'ve written a wrapper class around a 3rd party library that requires properties to be set by calling a Config method and passing a string formatted as \"Property=Value\"

I've written a wrapper class around a 3rd party library that requires properties to be set by calling a Config method and passing a string formatted as "Property=Value"

I'd like to pass all the properties in a single call and process them iteratively.

I've considered the following:

  • creating a property/value class and then creating a List of these objects
  • building a str开发者_JS百科ing of multiple "Property=Value" separating them with a token (maybe "|")
  • Using a hash table

All of these would work (and I'm thinking of using option 1) but is there a better way?

A bit more detail about my query:

The finished class will be included in a library for re-use in other applications. Whilst I don't currently see threading as a problem at the moment (our apps tend to just have a UI thread and a worker thread) it could become an issue in the future.

Garbage collection will not be an issue.

Access to arbitrary indices of the data source is not currently an issue.

Optimization is not currently an issue but clearly define the key/value pairs is important.


As you've already pointed out, any of the proposed solutions will accomplish the task as you've described it. What this means is that the only rational way to choose a particular method is to define your requirements:

  • Does your code need to support multiple threads accessing the data source simultaneously? If so, using a ConcurrentDictionary, as Yahia suggested, makes sense. Otherwise, there's no reason to incur the additional overhead and complexity of using a concurrent data structure.
  • Are you working in an environment where garbage collection is a problem (for example, an XNA game)? If so, any suggestion involving the concatenation of strings is going to be problematic.
  • Do you need O(1) access to arbitrary indices of the data source? If so, your third approach makes sense. On the other hand, if all you're doing is iterating over the collection, there's no reason to incur the additional overhead of inserting into a hashtable; use a List<KeyValuePair<String, String>> instead.
  • On the other hand, you may not be working in an environment where the optimization described above is necessary; the ability to clearly define the key/value pairs programatically may be more important to you. In which case using a Dictionary is a better choice.

You can't make an informed decision as to how to implement a feature without completely defining what the feature needs to do, and since you haven't done that, any answer given here will necessarily be incomplete.

Given your clarifications, I would personally suggest the following:

  • Avoid making your Config() method thread-safe by default, as per the MSDN guidelines:

    By default, class libraries should not be thread safe. Adding locks to create thread-safe code decreases performance, increases lock contention, and creates the possibility for deadlock bugs to occur.

  • If thread safety becomes important later, make it the caller's responsibility.

  • Given that you don't have special performance requirements, stick with a dictionary to allow key/value pairs to be easily defined and read.

  • For simplicity's sake, and to avoid generating lots of unnecessary strings doing concatenations, just pass the dictionary in directly and iterate over it.

Consider the following example:

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

And the implementation of 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
    }
}


You could use Dictionary<string,string>, the items are then of type KeyValuePair<string,string> (this correpsonds to your first idea) You can then use myDict.Select(kvp=>string.Format("{0}={1}",kvp.Key,kvp.Value)) to get a list of strings with the needed formatting


Use for example a ConcurrentDictionary<string,string> - it is thread-safe and really fast since most operations are implemented lock-free...


You could make a helper class that uses reflection to turn any class into a Property=Value collection

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 + "=";  
               }
          }
     } 
}

You would need to add extra logic to handle enumerations, indexed properties, etc.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号