2013-04-08 2 views
2

вопрос относительно выполнения отливки объекта к тому же типу (я знаю, что звучит странно на первый, но позвольте мне поставить его в контексте)Кастинг объект того же типа и влияния на производительность

public T Get<T>(string key) where T : class 
{ 
    var objToReturn = (T)_cache[key]; 
    if (objToReturn != null) 
    { 
     return objToReturn; 
    } 
    return null; 
} 

Вышеприведенный фрагмент кода для попытки получить объект типа T из CacheObject, где тип строго типизирован вызывающим.

Знаешь, видя, как тип объекта сильно типизированных, я задаюсь вопросом о линии:

var objToReturn = (T)_chache[key]; 

Будет ли это на самом деле ссылаться на бросок и преобразовать экземпляр в кэше другого экземпляра и вернуть ту или воли типы будут считаться одинаковыми для просто игнорируемых.

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

Мысли и спасибо.

+3

Основываясь на реализации вашего тела метода, он может быть реорганизован в одну строку: 'return _cache [key] as T;'. –

+0

@AndreasGrech: Нет, определенно нет, из-за возможности исключений - см. Мой ответ на ваш комментарий в моем ответе. –

ответ

3

Листинг, который вы показали, является естественным ссылочным типом. Он ничего не меняет об объекте - он просто гарантирует, что объект имеет соответствующий тип (либо тот, который вы производите, либо подкласс). Если объект имеет неправильный тип, генерируется исключение. Никакие дополнительные объекты не создаются или что-то в этом роде.

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

Это не понятно, почему вы получили этот код, хотя:

if (objToReturn != null) 
{ 
    return objToReturn; 
} 
return null; 

Почему бы не просто использовать:

return objToReturn; 

? Это будет вести себя точно так же. Тогда весь ваш метод может быть сведен к:

public T Get<T>(string key) where T : class 
{ 
    return (T) _cache[key]; 
} 

EDIT: Обратите внимание, что вы должны не просто использовать as вместо этого, если вы действительно не хотите значения неверного типа молча возвращаются в null. Например:

cache[key] = new object(); 
string x = cache[key] as string; // x is null 
string y = (string) cache[key]; // Exception 
+1

Jon, учитывая ограничение 'T: class', существует ли разница между использованием' (T) _cache [key] 'или' _cache [key] как T' для данного конкретного случая? –

+0

Дополнительный шаг находится там, где будет выполняться некоторая обработка, если объект не найден, который не был помещен в _yet_. Большое спасибо, хотя, что улаживает маленькое раздражение, которое у меня об этом, возможно, мешало. –

+0

'_cache [key] как T'-версия не может генерировать исключение, но версия' (T) _cache [key] 'может. –

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