0

For example,

I have input parameter of type object. And I know that this parameter can store one of value type int, float, double(boxed value) etc. But I don't know which value type will come to this method. And I want check if boxed value type empty or not.

Like this piece of code:

bool IsEmpty(object boxedProperty)
{
    return boxedProperty == default(typeof(boxedProperty))
}

I understand, I can do this:

bool IsEmpty(object boxedProperty)
{
    return boxedProperty is int && boxedProperty == default(int)
    || boxedProperty is float ....
}

But it looks like dirty solution. How do this better?

Oleksandr Nahirniak
  • 1,357
  • 2
  • 9
  • 12

3 Answers3

2

I guess something like this can give you a result for reference + boxed value types.

public bool IsDefaultValue(object o)
{
    if (o == null)
        return true;

    var type = o.GetType();
    return type.IsValueType && o.Equals(Activator.CreateInstance(type));
}

object i = default(int);
object j = default(float);
object k = default(double);
object s = default(string);

object i2 = (int)2;
object s2 = (string)"asas";


var bi = IsDefaultValue(i); // true
var bj = IsDefaultValue(j); // true
var bk = IsDefaultValue(k); // true
var bs = IsDefaultValue(s); // true

var bi2 = IsDefaultValue(i2); // false
var bs2 = IsDefaultValue(s2); // false

If you are shure you have a value type, then use this method:

public bool IsDefaultBoxedValueType(object o)
{
    return o.Equals(Activator.CreateInstance(o.GetType()));
}
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
1

As others have pointed out the only real way to do it is to create an instance of the type and then compare it. (see also how to get the default value of a type if the type is only known as System.Type? and Default value of a type at Runtime)

You can cache the results so you only have to create a default instance 1x type. This can increase efficiency if you have to call the check many times. I used a static method and dictionary (its not thread safe) but you could change it to instance level if you wanted.

static IDictionary<Type, object> DefaultValues = new Dictionary<Type, object>();
static bool IsBoxedDefault(object boxedProperty)
{
    if (boxedProperty == null)
        return true;
    Type objectType = boxedProperty.GetType();

    if (!objectType.IsValueType)
    {
        // throw exception or something else?? Up to how you want this to behave
        return false;
    }

    object defaultValue = null;
    if (!DefaultValues.TryGetValue(objectType, out defaultValue))
    {
        defaultValue = Activator.CreateInstance(objectType);
        DefaultValues[objectType] = defaultValue;
    }
    return defaultValue.Equals(boxedProperty);
}

Test code

static void Test()
{
    Console.WriteLine(IsBoxedDefault(0)); // true
    Console.WriteLine(IsBoxedDefault("")); // false (reference type)
    Console.WriteLine(IsBoxedDefault(1));// false
    Console.WriteLine(IsBoxedDefault(DateTime.Now)); // false
    Console.WriteLine(IsBoxedDefault(new DateTime())); // true
}
Community
  • 1
  • 1
Igor
  • 60,821
  • 10
  • 100
  • 175
0

Looks to my like a generic function is a fine way to go. Something similar to:

    static void Main(string[] args)
    {
        object obj1 = null;
        object obj2 = "Assigned value";

        Console.WriteLine(string.Format("IsEmpty(obj1) --> {0}", IsEmpty(obj1)));
        Console.WriteLine(string.Format("IsEmpty(obj2) --> {0}", IsEmpty(obj2)));

        Console.ReadLine();
    }

    private static bool IsEmpty<T>(T boxedProperty)
    {
        T defaultProperty = default(T);
        return ReferenceEquals(boxedProperty, defaultProperty);
    }

Outputs:

IsEmpty(obj1) --> True
IsEmpty(obj1) --> False
Cleptus
  • 3,446
  • 4
  • 28
  • 34