Search code examples
c#objectnulldefault-valuevalidationattribute

C# how to determine value wrapped within object is null or default?


I am currently writing on a custom required validation attribute, and I want to revert with the error when the value is null or Default. With Default I mean "" for String, 0 for int, 0.0 for double, null for object.

And to achieve that, I am calling the below function that works well for any type

    protected bool IsNullOrDefault<T>(T value)
    {
        return object.Equals(value, default(T));
    }

Here are the tests:

    object obj = null;
    bool flag = IsNullOrDefault(obj));

flag = True

    int i = 0;
    bool flag = IsNullOrDefault(i);

flag = True

    double d = 0.0;
    Console.WriteLine(IsNullOrDefault(d));

flag = True

    object value = 0;
    Console.WriteLine(IsNullOrDefault(value));

flag = False

Here the object in-turn contains int inside, but it still thinks it is an object, whose default value is null and current value is 0. So it returns False.

The problem is, the framework method I am overriding gives me the value as object, so it will always going to match with the last scenario mentioned above.

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    { ....
    }

As per the value how can we convert the object to the actual type which in this case is int? So that, I receive True even for the last scenario above.


Solution

  • Finally I am able to achieve this by casting the value with dynamic type,

        protected bool IsNullOrDefault(object obj)
        {
            bool retval = false;
            if (obj == null)
            {
                retval = true;
            }
            else
            {
                retval = IsEmpty((dynamic)obj);
            }
            return retval;
        }
    
        protected bool IsEmpty<T>(T value)
        {
            return object.Equals(value, default(T));
        }
    

    You should use dynamic type where you want the resolution of the type to take place at run time rather than at compile time. Because of this, in this case the value self determines it's type appropriately without we telling it.