Синтаксический сахар для броска с оператором null coalesce - PullRequest
1 голос
/ 16 декабря 2011

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

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

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

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

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

Ответы [ 4 ]

5 голосов
/ 16 декабря 2011

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

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

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

return possibleNull;
2 голосов
/ 16 декабря 2011

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

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

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

Condition.Requires(possibleNull , "possibleNull ").IsNotNull();
return possibleNull; 
2 голосов
/ 16 декабря 2011

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

public static class ThrowHelper
{
    public static TException ThrowIfNull<TException>(object value)
        where TException : Exception, new()
    {
        if (value == null) //or other checks
        {
          throw new TException();
        }
    }
}
2 голосов
/ 16 декабря 2011

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

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

...