2011-12-16 2 views
1

Давайте предположим, что мы хотим, чтобы бросить, если попытаться присвоить нуль к чему-то, что об этой уловке:синтаксический сахар для метания с оператором нулевой Coalesce

public static class ExceptionExtension 
    { 
     public static T Throw<T>(this Exception exc) 
     { 
      throw exc; 
     } 
    } 

, что мы можем использовать, например, как это:

return possibleNull ?? new Exception("Unspecified something....").Throw<string>(); 

Вы считаете, что это хорошая/худшая/бесполезная практика?

ответ

5

Это не имеет смысла для меня - не очень читаемо. Я бы ожидал, что второй аргумент оператора ?? будет того же типа possibleNull, чтобы не бросать экскремент.

Я предпочел бы видеть:

if(possibleNull == null) 
{ 
    throw new Exception("Unspecified something...."); 
} 

return possibleNull; 
+0

Да Oded это трюк, мне кажется приятным, но просто хочу другого мнения, спасибо! (+1) Я жду некоторых других, прежде чем пометить их как ответ. –

+0

@FelicePollano - я понимаю. Когда я пишу код, есть несколько вещей, которые мне нравится иметь в виду (поскольку другие читают его). 1. [Принцип наименьшего удивления] (http://en.wikipedia.org/wiki/Principle_of_least_astonishment). 2. Эта цитата: «Всегда указывайте, как будто парень, который заканчивает поддерживать ваш код, будет жестоким психопатом, который знает, где вы живете». Джон Ф. Вудс. – Oded

+0

Ok quote 2) убедил меня отметить ваш как ответ;) –

2

Вы всегда можете вставить его в какой-то короткое название статической вспомогательный класс:

public static class Never 
{ 
    public static T Null<T>(T value) 
     where T : class 
    { 
     if (value == null) throw new ArgumentNullException(); 
     return value; 
    } 
} 

myClass.AProperty = Never.Null(somePotentiallyNullValue); 

Ваш другой пример не имеет особого смысла, Я бы предпочел назвать это «бесполезной» практикой.

Добавление немного «беглости» в классы-помощники обычно фокусируется на том, чтобы сделать вещи более читаемыми.

http://en.wikipedia.org/wiki/Fluent_interface

+0

, в этом случае не удалось скомпилировать? –

+0

@FelicePollano 'return val ?? throw new' –

+0

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

2

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

public static class ThrowHelper 
{ 
    public static TException ThrowIfNull<TException>(object value) 
     where TException : Exception, new() 
    { 
     if (value == null) //or other checks 
     { 
      throw new TException(); 
     } 
    } 
} 
+0

+1 поблагодарить за мнение –

2

Я не считаю это хорошая практика.

Во-первых, сам метод расширения вводит метод для чего-то, к которому у нас уже есть ключевое слово: throw. Это может показаться странным. Он объявляет тип возврата, хотя он никогда не вернет значение, просто чтобы угодить компилятору в том контексте, где вы хотите его использовать. Ссылаясь на то, что уже указывали другие, это скорее «принцип наибольшего удивления».

Затем, глядя на то, как вы использовали этот метод, полученный код кажется не очень понятным для чтения. Еще хуже: вы можете использовать этот подход только в выражении, поэтому вы всегда будете иметь код, который каким-то образом использует объект (в вашем примере: просто верните его) и проверит его как null как побочный эффект в той же строке , Я предпочел бы делать явные проверки null и не смешивать с чем-то другим. Библиотека, подобная CuttingEdge.Conditions, может помочь уменьшить количество кода, который вы должны ввести для этого. Вы бы использовали его в своем примере таким образом

Condition.Requires(possibleNull , "possibleNull ").IsNotNull(); 
return possibleNull; 
+0

+1 поблагодарить за мнение –