代码之家  ›  专栏  ›  技术社区  ›  John

将对象中的空字符串转换为空字符串

c#
  •  5
  • John  · 技术社区  · 15 年前

    获取对象并将其任何值从null转换为string.empty最简单的方法是什么?

    我在想一个我可以在任何对象中传递的例程,但是我不确定如何循环遍历所有值。

    6 回复  |  直到 10 年前
        1
  •  14
  •   tanascius    15 年前

    当对象通过属性公开其值时,可以编写如下内容:

    string Value { get { return m_Value ?? string.Empty; } }
    

    另一种解决方案是使用反射。此代码将检查字符串类型的属性:

    var myObject = new MyObject();
    foreach( var propertyInfo in myObject.GetType().GetProperties() )
    {
        if(propertyInfo.PropertyType == typeof(string))
        {
            if( propertyInfo.GetValue( myObject, null ) == null )
            {
                propertyInfo.SetValue( myObject, string.Empty, null );
            }
        }
    }
    
        2
  •  9
  •   Dynami Le Savard    15 年前

    使用反射,您可以类似于:

    public static class Extensions
    {
        public static void Awesome<T>(this T myObject) where T : class
        {
            PropertyInfo[] properties = typeof(T).GetProperties();
            foreach(var info in properties)
            {
                // if a string and null, set to String.Empty
                if(info.PropertyType == typeof(string) && 
                   info.GetValue(myObject, null) == null)
                {
                    info.SetValue(myObject, String.Empty, null);
                }
            }
        }
    }
    
        3
  •  2
  •   MusiGenesis    15 年前

    大概,你在某个地方有一份报告或表格,上面到处都是“空的”,而不是一个漂亮的、令人愉快的“”。

    最好保持空值不变,并在适当的时候修改显示代码。因此,这样的一条线:

    label1.Text = someObject.ToString();
    

    应该成为:

    if (someObject == null)
    {
        label1.Text = ""; // or String.Empty, if you're one of *those* people
    }
    else
    {
        label1.Text = someObject.ToString();
    }
    

    您可以根据需要将其功能化:

    public void DisplayObject(Label label, Object someObject)
    {
        if (someObject == null)
        {
            label.Text = ""; // or String.Empty, if you're one of *those* people
        }
        else
        {
            label.Text = someObject.ToString();
        }
    }
    
        4
  •  0
  •   Darin Dimitrov    15 年前

    你可以用反射。下面是一个具有一个嵌套级别的示例:

    class Foo
    {
        public string Prop1 { get; set; }
        public string Prop2 { get; set; }
        public string Prop3 { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo
            {
                Prop1 = (string)null,
                Prop2 = (string)null,
                Prop3 = (string)null,
            };
    
            var props = typeof(Foo).GetProperties()
                .Where(x => x.PropertyType == typeof(string));
            foreach (var p in props)
            {
                p.SetValue(foo, string.Empty, null);
            }
        }
    }
    
        5
  •  0
  •   Jeffrey L Whitledge    15 年前

    你可以通过思考来做到这一点,而不会有太多的麻烦,我相信当我发表这篇文章时,将会有答案告诉你如何做到这一点。

    但我个人不喜欢反射选项。

    我更喜欢通过各种方法为对象的所有成员维护对象不变量。对于字符串成员,不变量通常不为空,有时也有最大长度要求(例如,对于数据库中的存储)。其他成员有其他类型的不变量。

    第一步是创建一个检查为对象定义的所有不变量的方法。

    [Conditional("DEBUG")]
    private void CheckObjectInvariant()
    {
        Debug.Assert(name != null);
        Debug.Assert(name.Length <= nameMaxLength);
        ...
    }
    

    然后在以任何方式操作对象的任何方法之后调用此函数。因为它是用 ConditionalAttribute ,这些调用都不会出现在应用程序的发布版本中。

    然后,您只需确保没有任何代码允许违反这些不变量。这意味着字符串字段的声明中需要有初始值设定项,或者需要在对象的所有构造函数中设置它们。

    一个特殊的问题,可能也是引起这个问题的原因,是如何处理自动属性。

    public string Name { get; set; }
    

    显然,可以在任何时候将其设置为空,对此您无能为力。

    关于自动属性有两个选项。首先,你完全不能使用它们。这完全避免了这个问题。其次,您可以只允许任何可能的字符串值。也就是说,使用该属性的任何代码都必须期望为空、10 MB字符串或介于两者之间的任何内容。

    即使使用反射选项移除空值,也必须知道何时对对象调用magic空值移除方法以避免 NullReferenceException S,所以你还没有真的那样买东西。

        6
  •  0
  •   ajpetersen    10 年前

    +1坦纳修斯的回答。我用了这个答案,但稍微修改了一下。

    首先,我只获取字符串属性,因此它不会循环遍历我的所有属性。其次,我将所有实体继承的BaseEntity类放在它中,这使它成为全局的,所以我不必将它放在所有实体上。

    public class BaseEntity
    {
        public int Id { get; set; }
    
        public BaseEntity()
        {
            var stringProperties = this.GetType().GetProperties().Where(x => x.PropertyType == typeof(string));
    
            foreach (var property in stringProperties)
            {
                if (property.GetValue(this, null) == null)
                {
                    property.SetValue(this, string.Empty, null);
                }
            }
        }
    }