简体   繁体   中英

check for null when using reflection

I am converting a object to csv using reflection. sometimes, i get null values which throws a exception and so i figured out to check for null and replace null with empty strings. However i get a error as i cannot convert object to string. The problem is in this line of code.

if(properties[i].GetValue(this) is String && string.IsNullOrEmpty(properties[i].GetValue(this)))

 public abstract class CsvableBase
 {
    public virtual string ToCsv()
    {
        string output = "";
        var properties = GetType().GetProperties();
        for (var i = 0; i < properties.Length; i++)
        {
            if(properties[i].GetValue(this) is DateTime)
            {
                 output +=((DateTime)properties[i].GetValue(this)).ToString("yyyy-MM-dd HH:mm:ss");
            }
            else if(properties[i].GetValue(this) is String && string.IsNullOrEmpty(properties[i].GetValue(this)))
            {
                 output += "";
            }
            else
            {
                 output +=   properties[i].GetValue(this).ToString();
            }

            if (i != properties.Length - 1)
            {
                output += ",";
            }
        }
        return output;
    }
}
//Read more at https://www.pluralsight.com/guides/microsoft-net/building-a-generic-csv-writer-reader-using-reflection#VHy18mLqdMT3EGR5.99

Though the value returned by GetValue() is a string at runtime, the return type of GetValue() is object , so you cannot pass it to string.IsNullOrEmpty() without casting.

You can do that:

if(properties[i].GetValue(this) is String s 
   && string.IsNullOrEmpty(s))

Before C# 7 it would have been a little more verbose:

object o = properties[i].GetValue(this);
string s = o as string;
if (string.IsNullOrEmpty(s))
{ /*...*/ }

You are over thinking it. Just evaluate the value once at the top of your for loop, and check for null once.

You don't need to try to distinguish between string-nulls and other types of null. At runtime they will all just null objects anyway.

You don't need to += "" because that doesn't do anything.

for (var i = 0; i < properties.Length; i++)
{
    object value = properties[i].GetValue(this);
    if (value == null)
    {
        //do nothing
    }
    else if (value is DateTime)
    {
         output += ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
    }
    else
    {
         output += value.ToString();
    }

    if (i != properties.Length - 1)
    {
        output += ",";
    }
}

Side note:

else if (properties[i].GetValue(this) is String && string.IsNullOrEmpty(properties[i].GetValue(this)))

is obvisouly wrong, because if the value was null then you have:

else if (null is String && string.IsNullOrEmpty(properties[i].GetValue(this)))

null is String is false.
The code on the right hand side will only run when the value is not null, which is pointless.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM