2012-06-12 45 views
3

我试图将可变属性信息转储到一个简单的字符串,但是当它到达我的可空布尔型时,as string总是返回null - 即使实际值为true,假!作为字符串的C#布尔值始终为空

StringBuilder propertyDump = new StringBuilder(); 

foreach(PropertyInfo property in typeof(MyClass).GetProperties()) 
{ 
    propertyDump.Append(property.Name) 
       .Append(":") 
       .Append(property.GetValue(myClassInstance, null) as string); 
} 

return propertyDump.ToString(); 

不引发任何异常;快速和输出正是我想要的,除了任何属性是bool?总是错误的。如果我快速看,并做.ToString()它的作品!但我不能保证其他属性实际上不是空的。

任何人都可以解释为什么这是?甚至更好,解决方法?

+4

这正是'as'是应该做的。 – SLaks

+0

如果值为空,我强烈建议附加“null”。你可以有一个字符串属性,它的值是“” - 是空还是空?你不知道。所以你最好使用'?:'或'''',这样空值将被写为“null”或其他空识别字符串。 – SimpleVar

回答

4

as运算符返回铸造值,如果该实例属于该确切类型,则返回铸造值,否则返回null

相反,你应该.Append(property.GetValue(...)); Append()将自动处理空值和转换。

+1

追加将处理空值,但它会通过不追加任何东西 - 可能或不需要。 –

0

您不能将bool转换为字符串。您必须使用ToString()

5

bool不是一个字符串,所以as运算符在你传递一个盒装布尔值时返回null。

在你的情况,你可以使用这样的:如果你想拥有空值只是不添加任何文本

object value = property.GetValue(myClassInstance, null); 

propertyDump.Append(property.Name) 
      .Append(":") 
      .Append(value == null ? "null" : value.ToString()); 

,你可以用Append(Object)直接:

propertyDump.Append(property.Name) 
      .Append(":") 
      .Append(property.GetValue(myClassInstance, null)); 

这将工作,但将“propertyDump”输出中的空属性保留为缺失的条目。

1

这是因为该属性的类型不是字符串。将其更改为:

Convert.ToString(property.GetValue(myClassInstance, null)) 

如果它为空,它将检索到null并且没关系。对于非空值,它将返回属性值的字符串表示

2

的最好的解决办法是,在我看来:

.Append(property.GetValue(myClassInstance, null) ?? "null"); 

如果该值为空,它会追加“空”,如果没有 - 它会调用值的ToString和追加一条。

相结合,与LINQ的,而不是一个foreach循环,你可以有一个可爱的小东西:

var propertyDump = 
    string.Join(Environment.NewLine, 
       typeof(myClass).GetProperties().Select(
        pi => string.Format("{0}: {1}", 
             pi.Name, 
             pi.GetValue(myClassInstance, null) ?? "null"))); 

(在VS的宽屏幕看起来更好)。

如果你比较速度,顺便说一下,结果是string.Join比追加到StringBuilder快,所以我想你可能想看到这个解决方案。

0

使用null coalesing operator处理空的情况:

void Main() 
{ 

    TestIt tbTrue = new TestIt() { BValue = true }; // Comment out assignment to see null 

    var result = 
    tbTrue.GetType() 
      .GetProperties() 
      .FirstOrDefault(prp => prp.Name == "BValue") 
      .GetValue(tb, null) ?? false.ToString(); 

     Console.WriteLine (result); // True 

} 

public class TestIt 
{ 
    public bool? BValue { get; set; } 
}