2010-08-05 24 views
1

У меня есть класс, который возвращает тип объекта переменной. Переменная должна знать, что реальный тип, когда операции выполняются на нем:Каков самый быстрый способ преобразования объекта Тип

свойство
public object Data 
    { 
     get 
     { 
      switch (CriteriaID) 
      { 
       case (int)matrix2.enums.NodeTypeEnums.Enums.MultiLineText: 
        return (string)_Data; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.SingleLineText: 
        return (string)_Data; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Number: 
        int temp = 0; 
        return int.TryParse((string)_Data, out temp) ? (int?)temp : null; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Price: 
        decimal temp1 = 0; 
        return decimal.TryParse((string)_Data, out temp1) ? (decimal?)temp1 : null; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.PullDown: 
        return (string)_Data; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Checkbox: 
        bool temp2 = false; 
        return bool.TryParse((string)_Data, out temp2) ? (bool?)temp2 : null; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Date: 
        DateTime temp3 = DateTime.MinValue; 
        return DateTime.TryParse((string)_Data, out temp3) ? ((DateTime?)temp3).Value.ToString("MM/dd/yyyy") : null; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Link: 
        return (string)_Data; 
       case (int)matrix2.enums.NodeTypeEnums.Enums.Image: 
        return (string)_Data; 
       default: 
        return (string)_Data; 
      } 
     } 
     set 
     { 
      _Data = value; 
     } 
    } 

данные используются следующим образом:

temp.Count() > 0 ? temp.FirstOrDefault().Data : " " 

С его помощью, как это работает, но я не уверен, если это является лучшей реализацией и/или наиболее эффективной. Их лучший способ сделать это?

+2

Используйте 'Any()' вместо 'Count()> 0', поскольку последний может завершиться перечислением всей последовательности. –

+2

Прошу прощения, но, бог, это самый ужасный код, который я когда-либо видел за всю свою жизнь. –

+0

@Brian Расмуссен: зачем использовать 'Any()', если 'FirstOrDefault()' уже проверяет, является ли последовательность пустой или нет? :-) – dtb

ответ

1

Чтобы быть честным, поскольку вы имеете дело с конечным числом возможных результатов, вы можете также использовать инструкцию switch. Что бы я сделал, многое изменилось, что вы делаете ...

Во-первых, не ставьте сложные операции с геттерами или сеттерами. Вы должны подтолкнуть их к отдельной методике:

public object Data 
{ 
    get 
    { 
    return FormatData(_Data); 
    } 
} 

Во-вторых, вам не нужно подавать в вашем случае блоков:

case (int)matrix2.enums.NodeTypeEnums.Enums.MultiLineText: 

В-третьих,

temp.Count() > 0 ? temp.FirstOrDefault().Data : " " 

... здесь имеется несколько вопросов, например,

temp.Count() > 0 

... заставит весь перечислимы переписываются, его гораздо более эффективным, чтобы сделать:

temp.Any() 

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

temp.FirstOrDefault().Data 

если вы звоните .Count() > 0 (или теперь, надеюсь, .Any()), вы можете изменить это на .First(), так как вы уже установили, что для этого пути должен быть экземпляр.

temp.FirstOrDefault().Data : "&nbsp"; 

Поскольку ваш метод потенциально возвращает, кроме строки типа, результат полных третичных операций может быть назначен только на объект, потому что компилятор не будет знать, какой тип аргумента он может быть назначен .... представьте, что вы возвращаете Int32 или String, какой?

UPDATE Теперь я думаю об этом, очень важное изменение, вы должны сделать это просто:

public object Data { get; set;} 

Свойство должно действительно просто вернуть исходные данные. Это должно быть вне проблемной области модели, что вы представляете данные (и, следовательно, преобразуете их в другие типы).

Похоже, вы, по сути, записываете объект в html, поэтому зачем все это делать с его форматированием?По большей части вы можете использовать .ToString(), чтобы получить строковое представление объекта:

temp.Any() ? temp.First().Data.ToString() : "nbsp;" 
+0

Ничего себе. Я изменил все свои подсчеты> 0 на любой ... Спасибо. Есть ли элегантный, чтобы реализовать свой последний совет? – Luke101

+0

См. Обновленный ответ –

+0

Спасибо. Ваше предложение работает – Luke101

0

Если предположить, что ваш тип происхождения совместим с типом назначения, вы можете сделать что-то вроде этого:

public T ConvertValue<T>(object value) 
{ 
    return (T)Convert.ChangeType(value, typeof(T), null); 
} 

(Или, если у вас есть перегрузка Convert.ChangeType, что не требует IFormatProvider)

public T ConvertValue<T>(object value) 
{ 
    return (T)Convert.ChangeType(value, typeof(T)); 
} 

А затем потреблять его, делая

int myValueConvertedToInt = ConvertValue<int>("12345"); 

Однако, если типы не являются несовместимы, то есть, вы пытаетесь что-то вроде

int myValueConvertedToInt = ConvertValue<int>("XXX"); 

Это отбросит. Поэтому вам захочется иметь сильную проверку на свойства, которые вы попытаетесь преобразовать. Я частично отношусь к атрибутам System.ComponentModel.DataAnnotations для привязки требований к проверке свойств.

+0

Если тип является объектом, и я не знаю реального типа, как я могу использовать Convert.ChangeType – Luke101

Смежные вопросы