2009-07-06 3 views
4

Есть ли способ сделать эту строку короче?null стенография в C#?

bool pass = d != null && d["k"] != null && (bool)d["k"]; 

Примечание: «k» на самом деле «более длинный идентификатор»; Я заменил его, чтобы сделать его более читаемым в этом сообщении. Многие из ваших предложений не проверяют, является ли d нулевым.

+0

Какой тип d? –

ответ

13

Попробуйте это:

bool pass = d != null && (bool)(d["k"] ?? false); 
+0

Thats гораздо приятнее: D – 2009-07-06 13:33:34

+0

+1 Я думаю, что это то, чем он был, оператор. Тем не менее, для проверки d все равно нужен. Я всегда думал, что было бы неплохо иметь каскадные ??? оператор, однако, я вижу множество причин, почему это было бы плохо! –

+1

Это не проверяет, существует ли значение в словаре. Если сбой при исключении null-ref, если «k» не существует. –

31

Это уже едва читаемо, так зачем делать его короче?

+4

Согласовано. Если что-нибудь должно быть длиннее или, по крайней мере, использовать лучшие имена переменных и индексов. – Welbog

+1

Согласованные - что представляют собой d и k? – RichardOD

+2

Где находится соединение? Короче говоря, это может улучшить * удобочитаемость. Сравнить 'x == null? "foo": x' to 'x ?? "Foo" '. Short == (потенциально) кратким. –

8

Я бы поставил под вопрос, почему вы пытаетесь сделать его короче.

Более короткий код никому не пригодится. Это еще труднее, если кто-то еще прочтет это.

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

Единственное «нулевое сокращение», доступное на C#, - это оператор null-coalescing, который позволяет определить значение по умолчанию для нулевого объекта. Но для вашего кода я бы рекомендовал ориентироваться на читаемость, а не на размер строки.

+1

Возможно, более короткий код подразумевает более быстрый код?: D –

+1

@Adrain: Может быть .... и, может быть, я напишу свой код в сборке .... может быть, я этого не делаю ... –

+0

Потому что частые «нулевые» чеки тоже нервничают. – peterchen

2

Я бы спросил, почему вы выбрали d ["k"] в bool. Либо это уже bool, либо его нужно сравнить с чем-то, чтобы получить bool. Это прояснит ситуацию.

Во всяком случае, я полагаю, что это может работать:

bool pass = (d != null) && d["k"] ?? false 
5

Да, извлечь функцию от него и назвать это что-то вроде doTheValuesInTheFooBarDictionaryPassTheRebarTest.

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

Короче говоря, чего вы надеетесь достичь? Быстрее читать? (мозгу потребуется больше времени, чтобы разобрать его!). Быстрее набрать? (вы набираете этот материал один раз и изменяете или читаете его снова и снова (и снова!)). Как правило, более длинные, более описательные переменные лучше, и если вы можете обернуть их методом инкапсуляции, сделайте это тоже.

+0

Не является поклонником извлечения 1-лайнера в метод с именем, которое даже труднее читать, чем одна строка кода, но концепция действительна для других случаев. –

+1

Я со Стивом здесь. Дать имя для таких лайнеров очень полезно, когда вы читаете код. И да, имя, предложенное Стивом, является примером, а не настоящим именем. – SolutionYogi

+0

Джеймс, это 1-слойный ТЕКСТ. Логично, что это многострочный: существует ли эта вещь. И если это так, содержит ли оно конкретное поле И если это так, попробуйте и принудительно введёте его в логическое значение. Без извлечения функции вы будете постоянно анализировать ВСЕ эти вещи (КАК), а не просто просматривать обзор того, что вам нужно (WHAT). –

4

Вы можете избавиться от первого выражения, инициализируя d в конструкторе. Я рекомендую использовать общий словарь i.e.

Dictionary<string,bool> d = new Dictionary<string,bool>(); 

Таким образом, вам не нужно указывать значение. И используйте метод ContainsKey, а не прямой доступ к значению. Так что ваше окончательное выражение

bool pass = d.ContainsKey("k") && d["k"]; 
1

Это не короче, но более надежным (и, возможно, немного более эффективным):

bool pass = false; 
if (d != null) 
{ 
    object value; 
    if (d.TryGetValue("k", out value)) 
    { 
     pass = value is bool && (bool)value; 
    } 
} 

Я рекомендовал бы двигаться в функцию.

2

Да. Сделайте d строго типизированным (например,использовать Словарь <> вместо Hashtable)

bool pass = d != null && d["k"]; 

Это помогло бы, если бы мы знали, тип D!

1

Вы можете заменить его с вызовом функции, которая принимает в словаре и ключ ...

3

Я бы не попытаться сократить его дальше, я хотел бы попытаться дать ему хорошее имя. Написание метода расширения или изменение класса (если у вас есть доступ к коду) звучит хорошо для меня.

// Better use a longer and more descriptive name here. 
public static Boolean Pass(this Foo foo, String bar) 
{ 
    return 
     (foo != null) 
     && (bar != null) // Maybe this test, too? 
     && (foo[bar] is Boolean) 
     && (foo[bar] as Boolean); 
} 

И используйте его так.

Boolean pass = d.Pass("k"); 
1

Я бы предпочел, чтобы увидеть что-то вроде этого:

bool pass = false; 
if(d != null && d["k"] != null) 
    pass = (bool)d["k"]; 

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

bool pass = false; 
if(!d.IsNull && !d["k"].IsNull) 
    pass = (bool)d["k"] 

Я нахожу это более понятным, чем оригинальная версия.

0

В C# 6 и выше, вы можете использовать

bool pass = (bool)(d?["k"] ?? false); 

Если тип компиляции время D [ "K"] является BOOL? Вы можете пропустить бросок

bool pass = d?["k"] ?? false; 
+0

Если тип времени '' d ["k"] '' '' '' '' '' ' object', это не сработает - я предполагаю, что есть причина для перевода в код OP. –

+0

Спасибо Jon - отредактирован. – kirodge

3

Комбинация нуль-условными и нуль-сливающихся операторы должны работать здесь:

bool pass = (bool) (d?["k"] ?? false); 

Для уточнения:

  • Если d имеет нулевое значение, d?["k"] is null
  • Если d?["k"] является null, d?["k"] ?? false является false (в штучной упаковке object)
  • Результат затем отливали

В качестве альтернативы можно подавать , прежде чем оператор нуль-коалесцирующий, но приведение к обнуляемого типа:

bool pass = ((bool?) d?["k"]) ?? false; 

Заметим, что нулевая - условный оператор был введен в C# 6.

+0

Ты мой герой! Я многому учусь от вас, спасибо! : D – fredyfx

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