Чистый способ приведения к объектам актуального типа - PullRequest
5 голосов
/ 16 февраля 2010

Что я делаю, так это поиск значения для определенного поля в хеш-таблице. Объект может быть горсткой примитивных типов, значение которых предназначено для помещения в XML, но он выходит из хеш-таблицы как объект. Поэтому у меня возникла проблема с необходимостью решить, что это за тип, привести его к типу и затем использовать этот тип ToString. Было бы хорошо, если бы мне не нужно было приводить его, но тогда он будет вызывать ToString для типа объекта, а не метод аналога для фактического типа.

Следующий код является функционально корректным, но мне это неудобно. Возможно, следование этому пути комфорта приведет к тому, что я стану пуристом. В любом случае я был бы очень признателен за лучший способ написать это, если таковой существует.

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

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

            if (value.GetType() == typeof(string))
            {
                return (string)value;
            }
            else if (value.GetType() == typeof(double))
            {
                return ((double)value).ToString();
            }
            ...
        }

Ответы [ 5 ]

8 голосов
/ 16 февраля 2010

Если все, что вы делаете, вызывает ToString, из-за полиморфной природы C #, ToString вызовет правильную реализацию, даже если все, что у вас есть, это ссылка на Object.

например:.

var d=DateTime.Now;
object od=d;
Console.WriteLine(od.ToString());
Console.WriteLine(d.ToString());   //same as previous line
1 голос
/ 16 февраля 2010

редактировать

Тестовые коды здесь, если кому-то интересно: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

Ниже вы найдете мой оригинальный ответ. Кто-то указал, что у вас может быть тип, у которого нет ToString (), который вам нравится (потому что он использует Object или что-то более высокое в цепочке). Лучший способ справиться с этим в 3.0+ - использовать метод расширения, подобный этому:

    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!";
       }
    }

Теперь mytype будет работать с приведенным ниже GetColumnValue, если вы измените ToString () на MyToString ()

оригинальный пост

Это будет делать то, что вы хотите.

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

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

        return object.ToString();
    }

или если вы хотите посмотреть старую школу:

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

конечно, настоящей старой школой было бы создание #define макроса ...

1 голос
/ 16 февраля 2010

В зависимости от вашего списка допустимых типов, вы можете рассмотреть возможность использования Convert.ToString и / или IConvertable интерфейса .

Это позволит вам обрабатывать большинство примитивных типов за один выстрел.

Однако вам все равно нужно будет обработать ваш нулевой чек.

0 голосов
/ 16 февраля 2010

ToString() - это виртуальный метод. Это означает, что при любых вызовах этого метода во время выполнения будет выбрана правильная реализация («наиболее производный тип»). Поскольку все примитивные типы переопределяют ToString() для правильной работы, нет никаких причин для приведения к любому типу переменной.

Для виртуального метода тип переменной не имеет значения при выборе правильной реализации. Все, что имеет значение, это тип времени выполнения объекта, на который ссылаются.

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

Оба вызова ToString() будут выполнять один и тот же код (за исключением распаковки, которая происходит в версии object, поскольку int - это тип значения).

0 голосов
/ 16 февраля 2010

Почему вы не можете просто использовать .ToString () для value, поскольку .ToString () наследуется от объекта? .ToString () для соответствующего типа далее по цепочке наследования будет вызван.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...