获取对象并将其任何值从null转换为string.empty的最简单方法是什么?
我在考虑一个可以在任何对象中传递的例程,但我不确定如何遍历所有值。
答案 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);
}
}
}
}