0

I did this:

businessCRM.Description = 
    string.Format("{0}\n" +
             "Name: {1}\n" +
             "Street: {2}\n " +
             "Number: {3}\n" +
             "floor: {4}\n" +
      business.Name,
      business.Address.Street,
      business.Address.Number,
      business.Address.floor,
);

And I would like to do the same but inversely in other method something like this to do way synchronization (round trip):

business.Address.Street = businessCRM.Description;
business.Address.Number = businessCRM.Description;
business.Address.floor = businessCRM.Description;

But I don't know if this is completely correct, any idea?

user1911
  • 680
  • 1
  • 14
  • 36
  • String.format is used completely wrong. Where is your format? What's more, you cannout simply "invere" foramtted string. You need to pare it firstly. –  Sep 05 '14 at 06:58
  • In first place your `string.Format` is wrong as first parameter is format string. Second: Why do you merge it if you need to access it individually? – Sriram Sakthivel Sep 05 '14 at 06:59
  • I updated code, you can see the code that I have now. – user1911 Sep 05 '14 at 07:00
  • Why you need to parse it from description? –  Sep 05 '14 at 07:01
  • Can your description perhaps contain something like json? then it would be trivial to do. The word you are looking for here is probably "serialization", btw - not "synchronization" – Marc Gravell Sep 05 '14 at 07:05
  • Yes, I use JSON too. The first code I can't modify it – user1911 Sep 05 '14 at 07:07

3 Answers3

0

The real solution would be to put an additional Address member in your businessCRM class, so you can store the data and the description and don't need to extract the data from the description later. Parsing it will only lead to problems.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • Can you put an example please? – user1911 Sep 05 '14 at 07:10
  • @user1911 An example is not possible without seeing your code. You never gave the class declaration of whatever businessCRM is. Post more code and I will give it a try. – nvoigt Sep 05 '14 at 07:40
0

You can pull it apart into a dictionary using something like the below; note I had to special-case the first line (has no prefix), and it won't work well if your data includes newlines internally in the values:

var parts = new Dictionary<string, string>(
    StringComparer.InvariantCultureIgnoreCase);
string firstLine;
using(var reader = new StringReader(description))
{
    string line;
    firstLine = reader.ReadLine();
    var splitBy = new[] { ':' };
    while ((line = reader.ReadLine()) != null)
    {
        var pair = line.Split(splitBy, 2, StringSplitOptions.None);
        if (pair.Length == 2) parts[pair[0].Trim()] = pair[1].Trim();
    }
}
string tmp;

string name, street, number, floor; // in your case, you could assign to
                                    // the properties directly
name = parts.TryGetValue("Name", out tmp) ? tmp : "";
street = parts.TryGetValue("Street", out tmp) ? tmp : "";
number = parts.TryGetValue("Number", out tmp) ? tmp : "";
floor = parts.TryGetValue("floor", out tmp) ? tmp : "";
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • BTW: `// in your case, you could assign to the properties directly`- its wrong - cannot use `out` with object properties, I mean: `myMethod("Name", out myObj.Name)` - causes compile time error. –  Sep 05 '14 at 07:34
  • @pwas you misunderstand; I mean "in place of the variables", i.e. `business.Address.Street = parts.TryGetValue("Street", out tmp) ? tmp : "";` etc – Marc Gravell Sep 05 '14 at 08:07
0

First of all see @Marc Gravell comment under question - it would be much easer to handle "deserialization". If not, here is solution.

  1. my code may be slow - you need to cache reflection info (like property info collection)
  2. there is no error handling and checking (ex. for nullity - do it manually ;))
  3. Code assumes that input is always proper input (f.e. new line char inside value), format etc.

Code:

var addressType = business.Address.GetType();

foreach (var line in businessCRM.Description
                                .Split(new[] { "\n", Environment.NewLine },
                                              StringSplitOptions.RemoveEmptyEntries))
{
    var propSelectorIndex = line.IndexOf(":");
    if (propSelectorIndex == -1) continue;

    var propName = line.Subtring(0, propSelectorIndex);
    var propInfo = addressType.GetProperties(BindigsFlag.Public 
                                                      | BindigsFlag.Instance)
                              .FirstOrDefault(prop => prop.Name == propName);

    if (propInfo == null) throw new InvalidOperationException();

    var newPropValue = line.Substring(propSelectorIndex + 2); 
                 // + 2 to omit : char and additional space
    propInfo.SetValue(business.Address, newPropValue, null);
}