How to get the lowercase name of an object, even when null, in C#

Viewed 59369

I have the C# method

private static string TypeNameLower(object o)
{
   return o.GetType().Name.ToLower();
}

to give me the lower case type name of the input object.

But if input is a string set to null or a nullable int set to null then this method of course fails.

How do I get the type name in this situation?

11 Answers

Jeff is correct. That's like asking what kind of cake would have been in an empty box with no label.

As an alternative to Fortran's answer you could also do:

string TypeNameLower<T>(T obj) {
   return typeof(T).Name.ToLower(CultureInfo.InvariantCulture);
}

string TypeNameLower(object obj) {
   if (obj != null) { return obj.GetType().Name.ToLower(CultureInfo.InvariantCulture); }
   else { return null; }
}

string s = null;
TypeNameLower(s); // goes to the generic version

That way, C# will pick the generic one at compile time if it knows enough about the type you're passing in.

// Uses the compiler's type inference mechanisms for generics to find out the type
// 'self' was declared with in the current scope.
static public Type GetDeclaredType<TSelf>(TSelf self)
{
    return typeof(TSelf);
}

void Main()
{
    // ...

    Foo bar;
    bar = null;

    Type myType = GetDeclaredType(bar);
    Console.Write(myType.Name);
}

Prints:

Foo

I posted this also at a similar topic, I hope it's of any use for you. ;-)

if (o == null) return "null";
else return o.GetType().Name.ToLower();

simple solution for a simple problem :-p

As others mention, you can't. This is actually a well-known issue with languages that allow pure null references to objects. One way to work around it is to use the "Null Object pattern". The basic idea is that instead of using null for empty references, you assign to it an instance of a "do nothing" object. For example:

public class Circle
{
    public virtual float Radius { get; set; }

    public Circle(float radius)
    {
        Radius = radius;
    }
}

public class NullCircle : Circle
{
    public override float Radius 
    { 
        get { return float.NaN; }
        set { }
    }

    public NullCircle() { }
}

You can then pass an instance of NullCircle instead of null and you will be able to test its type like in your code.

To the best of my knowledge you can't. Null indicates the absence of a value and is not distinct for different types.

There is no notion that a null string is different than a null Array is different than a null anything else. From inside your function, you cannot determine the type name.

More specifically, an instance of a reference class (internally) includes a "pointer" to the type information about the object. When the input is null, there is no such pointer so the type information does not exist.

If you have an object by itself (let's say as an input parameter to a method with type object), with no definition or generic type, there is no way to find the type. The reason is simple, you cannot send message to (invoke any method on) the object to ask about the type.

There could be some other workarounds, as you see in some answers, like using generic types. In that case, you're not asking the Null object, you are asking the generic type for its type.

Consider this code:

    public class MyClass1{}
    public class MyClass2{}

    public static void Test1()
    {
        MyClass1 one = null;
        MyClass2 two = (MyClass2) (object) one;

        one = new MyClass1();
        //invalid cast exception
        two = (MyClass2)(object) one;
    }

The runtime-type of a null instance is object, at least from a type-safety point of view.

Related