I'm attempting to dump variable property information to a simple string but when it gets to my nullable bools, the as string
always returns null --even if the actual value is true | false!
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();
No exceptions are thrown; quick and the output is exactly what I want except any properties that are bool?
are always false. If I quick watch and do .ToString()
it works! But I can't guarantee other properties are not, in fact, null.
Can anyone explain why this is? and even better, a workaround?
A bool is not a string, so the as operator returns null when you pass it a boxed boolean.
In your case, you could use something like:
object value = property.GetValue(myClassInstance, null);
propertyDump.Append(property.Name)
.Append(":")
.Append(value == null ? "null" : value.ToString());
If you want to have null values just not append any text, you can just use Append(Object) directly:
propertyDump.Append(property.Name)
.Append(":")
.Append(property.GetValue(myClassInstance, null));
This will work, but leave null properties in your "propertyDump" output as missing entries.
The as
operator returns a casted value if the instance is of that exact type, or null
otherwise.
Instead, you just should .Append(property.GetValue(...))
; Append()
will automatically handle nulls and conversions.
The nicest solution would be, in my opinion:
.Append(property.GetValue(myClassInstance, null) ?? "null");
If the value is null, it will append "null", and if not - it will call the value's ToString and append that.
Combining that with Linq instead of a foreach loop, you can have a nice little something:
var propertyDump =
string.Join(Environment.NewLine,
typeof(myClass).GetProperties().Select(
pi => string.Format("{0}: {1}",
pi.Name,
pi.GetValue(myClassInstance, null) ?? "null")));
(Looks nicer in the wide screen of VS).
If you compare speeds, by the way, it turns out the string.Join is faster than Appending to a StringBuilder, so I thought you might want to see this solution.
That's because the type of the property is not string. Change it to:
Convert.ToString(property.GetValue(myClassInstance, null))
If it's null, it will retrieve null and that's ok. For non-null values it will return the string representation of the value of the property.
You cannot cast a bool to a string. You must use ToString()
Use the null coalesing operator to handle the Null situations:
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; }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.