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

时间:2010-04-06 14:28:39

标签: c#

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

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

6 个答案:

答案 0 :(得分:14)

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

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

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

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 :(得分:9)

使用反射,你可以使用类似的东西:

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

答案 2 :(得分: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();
    }
}

答案 3 :(得分: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);
        }
    }
}

答案 4 :(得分: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,所以你还没有真正买任何东西那样。

答案 5 :(得分: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);
            }
        }
    }
}