减少重复的属性结构

时间:2016-04-04 22:12:18

标签: c# properties

我有一个类,其中包含许多代表客户的自动字符串属性。简而言之,这样的事情:

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

此数据来自使用Nuget包的客户端和许多不同的文件导入。这些客户端似乎是在数据库生成的系统中复制数据,我们在某些字段中有时会得到文字“NULL”字符串。我想以一种简单的方式去除它们,尽可能地对现有代码进行一些改动。我不希望抛出错误,我只是希望它为null而不是“NULL”(不是Address2的验证失败,而是LastName)。

因为有很多导入而且我在没有源的情况下使用Nuget的库,所以我无法真正捕获到的数据。所有这些都在我们处理它之前以相当少的类结束,所以这似乎是做这件事的地方。我在这里列出了两个字段,但是有十几个字段,而且它不仅仅是一个类。我们也经常使用ValueInjector,因此为自定义类交换字符串实际上并不是一种选择。

我能想到的最好的方法是撤消自动属性并使用字符串扩展方法进行空检查。这似乎是一大堆重复的臃肿。有没有办法在一个属性上定义这个动作,并且每次都这样做,而不是将一行代码转换成十三十次?

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;
        }
    }
}

注意我不是在谈论代码格式化。我们有足够的StyleCop和CodeAnalysis规则来保持扩展类似于上面的内容,这在你真正想要阅读的代码时很好。

1 个答案:

答案 0 :(得分:0)

我放弃了尝试不触及每个导入。我只是在导入查找任何可编辑字符串属性的数据后调用了一个通用的扩展方法,检查“NULL”或空字符串并将其转换为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;
}

由于它一般返回传递的对象,我可以在投影中使用它:

IEnumerable<Person> = personList.Select(p => p.CleanNullishStrings());