-1

I have a class with many automatic string properties representing a customer. Briefly, something like this:

public class Person 
{    
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

This data comes from clients and many different file imports using a Nuget package. Those clients appear to be copying their data out of a database-generated system where we get literal "NULL" strings sometimes in some fields. I'd like to strip those out in an easy fashion with a little change to existing code as possible. I don't want errors thrown, I just want it to be null instead of "NULL" (not a validation failure for Address2, but is for LastName).

Because there are many imports and I'm using a library off Nuget without the source, I can't really catch the data coming in. All of it ends up in a pretty small number of classes before we process it, so this seems like the place to do it. I list two fields here, but there are over a dozen, and it's not just one class. We also use ValueInjector a lot, so swapping out string for a custom class isn't really an option.

The best I can come up with is undoing the auto-properties and using a string extension method for the null check. That just seems like a whole lot of repeated bloat. Is there any way to define this action on a property and say do that every time without turning one line of code into thirteen dozens of times over?

public static class StringExtensions
{
    public static string NullMeansNull(this string value)
    {
        if (value == "NULL")
            return null;
        else
            return value;
    }
}

public class Person 
{
    private string _FirstName;
    public string FirstName
    {
        get
        {
            return this._FirstName.NullMeansNull();
        }

        set
        {
            this._FirstName = value;
        }
    }

    private string _LastName;
    public string LastName
    {
        get
        {
            return this._LastName.NullMeansNull();
        }

        set
        {
            this._LastName = value;
        }
    }
}

Note I'm not talking about code formatting. We have enough StyleCop and CodeAnalysis rules that keep things expanded similar to above, which is good when it's code you actually want to read.

icrf
  • 364
  • 3
  • 13
  • http://stackoverflow.com/questions/8388964/how-can-i-inherit-the-string-class might help you ( implicit operator - that made class acting as a string) – Vladimir Apr 04 '16 at 22:40
  • That is interesting. I've never seen an implicit operator before. Unfortunately, ValueInjector is super picky about types, and only copies properties if they're exactly the same type. It won't even copy a Guid into a Nullable property. – icrf Apr 05 '16 at 13:14

1 Answers1

0

I gave up trying not to touch each import. I just made a generic extension method I call after importing data that looks for any editable string property, checking for "NULL" or empty string and converting it to null.

public static T CleanNullishStrings<T>(this T obj) where T : class
{
    foreach (System.Reflection.PropertyInfo property in obj.GetType().GetProperties())
    {
        if (property.PropertyType == typeof(string) && property.CanRead && property.CanWrite)
        {
            string value = (string)property.GetMethod.Invoke(obj, null);
            value = string.IsNullOrEmpty(value) || value.ToUpper() == "NULL" ? null : value;
            property.SetMethod.Invoke(obj, new object[] { value });
        }
    }

    return obj;
}

Since it generically returns the object passed, I can use it in projections:

IEnumerable<Person> = personList.Select(p => p.CleanNullishStrings());
icrf
  • 364
  • 3
  • 13