开发者

A clean way to cast to an objects actual type

What I'm doing is looking up a value for a particular field in the hashtable. The object can be a handful of primitive types who's value is destined to be put inside XML but it comes out of the hashtable as an object. So I have the problem of needing to decide what the type is, cast it up and then use that types ToString. It would be nice if I didn't need to cast it but then it will call the ToString on the object type and not the counterpart method on the actual type.

The following code is functionally correct, but I'm not comfortable with it. Perhaps following this comfort path will lead to me being a purist. Either way I would very much appreciate a nicer way to write this if such exists.

public string GetColumnValue(string columnName)
        {
            object value = item[columnName];

            if (value == null)
                return string.Empty;

            if (value.GetType() == typeof(string))
            {
     开发者_JS百科           return (string)value;
            }
            else if (value.GetType() == typeof(double))
            {
                return ((double)value).ToString();
            }
            ...
        }


If all you are doing is calling ToString, due to the polymorphic nature of C#, the ToString will call the correct implementation, even if all you have is a reference to Object.

E.g.:

var d=DateTime.Now;
object od=d;
Console.WriteLine(od.ToString());
Console.WriteLine(d.ToString());   //same as previous line


Depending on your list of acceptable types, you may want to consider using Convert.ToString and/or the IConvertable interface.

This will allow you to handle most of the primitive types in one shot.

You will still need to handle your null check, however.


edit

Test codes are here if anyone is interested: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

Below you will find my original answer. Someone pointed out that you might have a type which does not have a ToString() you like (because it uses Object or something higher up in the chain). The best way to handle this in 3.0+ is with a extension method like this:

    public static class ToStringExpander
    {
       public static string MyToString (this Object x)
       {
          return x.ToString();
       }

       public static string MyToString (this mytype x)
       {
          return "This is the to string of mytype!";
       }
    }

Now mytype will work with the GetColumnValue below if you change ToString() to MyToString()

original post

This will do what you want.

   public string GetColumnValue(string columnName)
    {
        object value = item[columnName];

        if (value == null)
            return string.Empty;

        return object.ToString();
    }

or if you want to look old school:

   public string GetColumnValue(string columnName)
    {
        return (item[columnName] == null ? string.Empty : item[columnName].ToString());
    }

of course true old school would be to make a #define macro...


Why can't you just use .ToString() on value since .ToString() is inherited from object? The .ToString() for the appropriate type further up the inheritance chain will be called.


ToString() is a virtual method. This means that any calls to that method will, at runtime, select the correct implementation (the "most derived type"). Since all the primative types override ToString() to do the correct thing, there is no reason for any casting to any type of variable.

For a virtual method, the type of the variable does not matter in selecting the correct implementation. All that matters is runtime type of the object being referenced.

int x = 10;
object o = x;
x.ToString();
o.ToString();

Both calls to ToString() will execute the same code (minus the unboxing that occurs in the object version, since int is a value type).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜