2010-04-06 207 views
4

将对象的任何值从null转换为string.empty的最简单方法是什么?在对象中将空字符串转换为空字符串

我正在考虑可以传入任何对象的例程,但我不知道如何遍历所有值。

+0

您的意思是,将'object'的所有'string'属性从null变为'String.Empty'? – 2010-04-06 14:31:12

+0

任何“其”值?你想检查什么类型的对象? – Thomas 2010-04-06 14:31:43

回答

12

当你的对象通过属性暴露了它的价值,你可以写这样的:

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); 
     } 
    } 
} 
+1

也许在SetValue之前进一步检查:if(propertyInfo.CanWrite)将有助于防止类只有null为 的只读属性。 – 2017-02-22 13:14:26

8

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

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); 
      } 
     } 
    } 
} 
+0

+1全球美丽的答案!虽然没有通用它不会工作吗?使用对象,而不是做myObject.GetType()。GetProperties(),而不是typeof(T).GetProperties() – BritishDeveloper 2010-04-06 14:48:04

+0

但是你应该在覆盖之前检查'value == null'是否正如你的评论建议^^ – tanascius 2010-04-06 14:51:00

+0

的确我应该; 0 – 2010-04-06 14:58:05

0

您可以使用反射。下面是与一级嵌套的例子:

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

想必,你有一个报表或窗体显示的地方,而不是一个美好,舒适“”“空”所有的地方。

最好将空值保留原样,并在适当的位置修改显示代码。因此,像这样的一行:

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(); 
    } 
} 
0

你可以做到这一点通过没有太多的麻烦反思,我相信在我发布这篇文章时,会有答案告诉你如何做到这一点。

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

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

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

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

然后你在以任何方式操纵对象之后调用此方法。由于它是用ConditionalAttribute装饰的,所以这些调用都不会出现在应用程序的发布版本中。

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

一个特殊的问题,可能是出于这个问题的动机之一,那就是如何处理自动属性。

public string Name { get; set; } 

显然,这可以在任何时候都设置为null,并且没有什么可以做的。

有两个关于自动属性的选项。首先,你根本不能使用它们。这完全避免了这个问题。其次,你可以允许任何可能的字符串值。也就是说,使用该属性的任何代码必须预期为空值,10 mb字符串或其中任何内容。

即使您使用反射选项删除空值,您仍然必须知道何时对对象调用magic-null-removal方法以避免NullReferenceException s,所以您没有真正购买任何东西。

0

+1给Tanascius的回答。我使用这个答案,但调整了一下。

首先,我只抓取字符串的属性,所以它不遍历我所有的属性。其次,我把我的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); 
      } 
     } 
    } 
}