2010-04-06 2 views
4

Что такое самый простой способ взять объекты и преобразовать любые его значения из null в string.empty?Преобразование нулей в пустую строку в объекте

Я думал о рутине, которую я могу передать в любом объекте, но я не уверен, как пройти все значения.

+0

Вы имеете в виду, что все свойства 'string'' объекта 'от' до 'String.Empty'? –

+0

Любые значения «его»? Каков тип объекта, который вы хотите проверить? – Thomas

ответ

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

Возможно, дополнительная проверка: 'if (propertyInfo.CanWrite)' непосредственно перед тем, как SetValue будет полезен для предотвращения исключений, когда классы имеют нулевое значение свойств readonly. –

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

+0

Но вы должны проверить, действительно ли 'значение == null' просто переписывается ... поскольку ваш комментарий предлагает ^^ – tanascius

+0

Действительно Я должен 0 –

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

Вы можете сделать это с помощью отражения без особых проблем, и я уверен, что к тому времени, когда я опубликую это, будут ответы, которые расскажут вам, как это сделать.

Но я лично не люблю вариант отражения.

Я предпочитаю поддерживать инварианты объектов для всех членов объекта с помощью различных средств. Для членов строки инвариант часто означает, что он не является нулевым, а иногда также требуются максимальные требования длины (например, для хранения в базе данных). Другие члены имеют другие виды инвариантов.

Первым шагом является создание метода, который проверяет все инварианты, которые вы определяете для объекта.

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

Тогда вы вызываете это после любого метода, который каким-либо образом манипулирует объектом. Поскольку он украшен ConditionalAttribute, ни один из этих вызовов не появится в версии приложения.

Тогда вам просто нужно убедиться, что ни один из кодов не допускает каких-либо нарушений этих инвариантов. Это означает, что в строковых полях должны быть либо инициализаторы в своих объявлениях, либо они должны быть установлены во всех конструкторах для объекта.

Специальная проблема, которая, вероятно, мотивировала этот вопрос, заключается в том, что делать с автоматическими свойствами.

public string Name { get; set; } 

Очевидно, что это может быть установлено в нуль в любое время, и вы ничего не можете с этим поделать.

Существует два варианта автоматического свойства. Во-первых, вы можете просто не использовать их вообще. Это полностью устраняет проблему. Во-вторых, вы можете просто разрешить любое возможное строковое значение. То есть любой код, который использует это свойство, должен ожидать нули, строки 10 мб или что-то среднее между ними.

Даже если вы используете опцию отражения для удаления нулей, вам все равно нужно знать, когда следует называть метод magic-null-remove на объекте, чтобы избежать NullReferenceException, так что вы действительно ничего не купили.

0

+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); 
      } 
     } 
    } 
} 
Смежные вопросы