2016-12-06 2 views
6

Какой из следующих двух эквивалентных способов лучше всего подходит для оператора с нулевым условием с точки зрения производительности, а затем простоты использования или четкости и т. Д.?C# 6.0 несколько идентичных нулевых операторов условного оператора против единой традиционной проверки

Это:

idString = child?.Id; 
fatherName = child?.Father?.Name; 
motherName = child?.Mother?.Name; 

или (при условии, что все локальные вары равны нулю уже) это:

if (child != null) 
{ 
    idString = child.Id; 
    fatherName = child.Father?.Name; 
    motherName = child.Mother?.Name;  
} 

Является ли производительность даже вопрос?

+6

Они не эквивалентны - последний код не присваивает * ничего * переменным, если «child» имеет значение null, тогда как прежний код будет присваивать значения null всем переменным в этом случае. Определите, какое поведение вы хотите в первую очередь, затем выберите то, что вы считаете наиболее читаемым, а затем подтвердите, что производительность соответствует вашим требованиям. (Если вы еще не определили свои требования к производительности, это первое, что нужно сделать ...) –

+0

Эти два эквивалента в том смысле, что они дают одинаковый результат. Результат гарантированно будет таким же, если, как я уже указывал, локальные вары уже нулевые. – GDS

+4

Ах, я не заметил, что «все локальные вары уже нулевые». В этом случае, который вы предпочитаете читать, и соответствует ли эта версия вашим критериям эффективности? (Вы не должны просто слепо идти на «лучшую» производительность - большинство кода на самом деле не критично, но * является критически важным для чтения.) –

ответ

6

Является ли производительность даже проблемой?

Краткий ответ: Производительность по проверке нулей никогда не будет проблемой в обычном приложении. Это только вопрос читаемости и ремонтопригодности.

Производительность:

Да, у вас есть 3 "явные" чеки против 1. Но вы должны иметь в виду, что:

  1. Система выполняет операцию "неявное" null-check каждый раз, когда вы ссылаетесь на экземпляр объекта, как объясняется here, а afaik JIT не оптимизирует нулевые проверки вообще. Таким образом, в вашем случае ставка не равна 3 от 1.
  2. Нулевая проверка - очень (действительно, очень) дешевой операцией по сравнению с большинством операций, которые вы выполняете в обычном потоке программного обеспечения (распределение кучи экземпляра, математическое вычисления, запрос linq, рендеринг графического объекта, синтаксический анализ строк, ...).

Я вижу лишь отдаленную возможность существенных отличий производительности: если child или Mother или Father не являются локальными переменными или простые простые свойства, но методы и свойства с очень долго время выполнения.Например, метод GetChild(), который выполняет 2 секунды для выполнения. Вы видите реалистичный сценарий для этого? Я не могу. Даже если это так, вы можете позвонить GetChild() один раз и назначить его локальной переменной, а затем позвонить child? 3 раза.

Читаемость:

Один начальный if позволяет мысленно отдельные разные куски кода. Притворись читателем кода, не зная ничего другого: спросите себя, проще ли читать «если ребенок не является нулевым, выполните все эти операции и прочее, иначе просто перейдите на«, или », если ребенок не является null проверить имя. Если снова ребенок не является нулевым, проверьте Мать. Если мать не является нулевой, получите имя матери. Затем, если снова ребенок не является нулевым, проверьте Отца. Если отец не является нулевым ... ... .. . ".

ремонтопригодность:

Ака, в этом случае DRY principle. Например, почему бы вы повторить нулевую проверку 3 раза? Представьте, что в определенный момент в будущем ваш босс попросит вас изменить код: требуется не только проверить недействительность дочернего элемента, но также и его Id - 0 (такие вещи случаются очень часто в любом процессе разработки программного обеспечения). В первом разделе кода вы должны исправить 3 строки. В вашем втором разделе кода вы должны исправить только одну строку: начальную if.

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

EDIT:

Для обсуждения безопасности потоков на нуль условного оператора, см this question.

+0

Downvoter, вы нашли 2 минуты, чтобы прочитать мой ответ, и, я думаю, - чтобы понять это ... не могли бы вы найти 20-30 дополнительных секунд, чтобы объяснить, что мне не хватает? –

+0

Я не сторонник, но могу предположить, что ваш пост, похоже, не отвечает на все части фундаментального вопроса настолько, насколько это кажется оправданием, чтобы использовать только одну часть. Держите свои ответы короткими и конкретными вопросами, поднятыми в вопросе. – dviljoen

+1

@ dviljoen Итальянскому парню, как я, всегда сложно выразить мысль простым и коротким предложениям, ах ... Но SO - хороший тренажерный зал. Я переписал свой ответ, но он еще длинный. Поскольку вопрос касался «производительности», «простой в использовании» и «ясности», минимальным является предоставление некоторых полезных элементов ... не так ли? Вы видите другие съемные/упрощенные детали? –

1

Во втором примере кода для переменных не будут установлены новые значения, но в первом примере они устанавливаются как null или значение из указанных свойств.

Названия операторов ?., такие как оператор с нулевым условием. Этот оператор работает как:

С помощью ?.:

var result = someProperty?.someField; 

Без использования ?.:

if (someProperty != null) 
    result = someProperty.someField; 
else 
    result = null; 

Об этом оператора вы можете прочитать здесь: https://msdn.microsoft.com/en-us/library/dn986595.aspx.

Лучше использовать его в fluent методов вызова. В вашем примере лучше использовать второй вариант, потому что если child имеет значение NULL, другие действия не выполняются.

+1

Это не отвечает на его вопрос. –

+0

Хм ... Я объяснил, в чем разница между примерами. Определенно сказать, что лучше, вы не можете зависеть от контекста использования. Второй - быстрее, но вдруг он должен поставить значения Null? Что тебе не нравится? – EgoPingvina

+1

Вопрос был: «Является ли производительность даже проблемой?», Которая имеет больше соображений, таких как читаемость и ремонтопригодность, контекст, в котором работает этот код (возможно, производительность этой проверки бессмысленна, потому что огромный алгоритм работает сразу после этого) и т. Д. То, что вы сказали, не ошибочно, просто не говорит, что «производительность - это даже проблема». –

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