2010-04-06 232 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); 
      } 
     } 
    } 
}