Злое использование, Возможно, монады и дополнительных методов в C#?

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

List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);

сделанный Job.

35
задан Judah Gabriel Himango 9 October 2015 в 17:38
поделиться

6 ответов

Интересно, что так много людей самостоятельно выбирают имя IfNotNull , для этого в C # - it должно быть самое разумное имя! :)

Самый ранний, который я нашел на SO: Возможные подводные камни использования этого сокращения (на основе метода расширения)

Мой (без учета вышеизложенного): Перенаправляет конвейер в C #

Другой более свежий пример: Как проверить наличие нулей в глубоком лямбда-выражении?

Существует несколько причин, по которым метод расширения IfNotNull может быть непопулярным.

  1. Некоторые люди непреклонны в том, что метод расширения должен генерировать исключение, если его этот параметр равен null . Я не согласен, если название метода ясно показывает.

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

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

Я В итоге получился простой автономный класс Maybe с одним статическим методом (не методом расширения), и это мне очень хорошо подходит. Но потом я работаю с небольшой командой, и мой следующий старший коллега интересуется функциональным программированием, лямбдами и т. Д., Поэтому его это не пугает.

В итоге мы получили простой автономный класс Maybe с одним статическим методом (не методом расширения), и это очень хорошо работает для меня. Но потом я работаю с небольшой командой, и мой следующий старший коллега интересуется функциональным программированием, лямбдами и т. Д., Поэтому его это не пугает.

В итоге мы получили простой автономный класс Maybe с одним статическим методом (не методом расширения), и это мне очень понравилось. Но потом я работаю с небольшой командой, и мой следующий старший коллега интересуется функциональным программированием, лямбдами и т. Д., Поэтому его это не пугает.

18
ответ дан 27 November 2019 в 15:43
поделиться

Как бы я ни был поклонником методов расширения, я не думаю, что это действительно полезно. У вас все еще есть повторение выражений (в монадической версии), и это просто означает, что вы должны объяснить Может быть всем. В этом случае дополнительная кривая обучения, похоже, не приносит достаточной пользы.

Версия IfNotNull , по крайней мере, позволяет избежать повторения, но я думаю, что она все еще слишком затянута, но на самом деле не яснее .

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


Кстати, мой любимый полузлой ​​метод расширения:

public static void ThrowIfNull<T>(this T value, string name) where T : class
{
    if (value == null)
    {
        throw new ArgumentNullException(name);
    }
}

Он позволяет вам превратить это:

void Foo(string x, string y)
{
    if (x == null)
    {
        throw new ArgumentNullException(nameof(x));
    }
    if (y == null)
    {
        throw new ArgumentNullException(nameof(y));
    }
    ...
}

в :

void Foo(string x, string y)
{
    x.ThrowIfNull(nameof(x));
    y.ThrowIfNull(nameof(y));
    ...
}

Все еще есть неприятное повторение имени параметра, но, по крайней мере, оно аккуратнее. Конечно, в .NET 4.0 я бы использовал контракты кода,

14
ответ дан 27 November 2019 в 15:43
поделиться

Если вы хотите, чтобы метод расширения уменьшал вложенные if, как у вас, вы можете попробовать что-то вроде этого:

public static object GetProperty(this object o, Type t, string p)
{
    if (o != null)
    {
        PropertyInfo pi = t.GetProperty(p);
        if (pi != null)
        {
            return pi.GetValue(o, null);
        }
        return null;
    }
    return null;
}

, так что в своем коде вы просто сделаете:

string activeControlName = (Form.ActiveForm as object)
    .GetProperty(typeof(Form),"ActiveControl")
    .GetProperty(typeof(Control),"Name");

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

(Примечание: я мог перепутать эти типы) :)

1
ответ дан 27 November 2019 в 15:43
поделиться

Начальный пример работает, и его легче всего прочитать с первого взгляда. Действительно ли есть необходимость улучшить это?

0
ответ дан 27 November 2019 в 15:43
поделиться

Решение IfNotNull является лучшим (пока команда C # не предоставит нам нулевой безопасный оператор разыменования, то есть).

0
ответ дан 27 November 2019 в 15:43
поделиться

Мне не очень нравится ни одно из этих решений. Что было не так в укороченной версии оригинала:

string activeControlName = null;
if (Form.ActiveForm != null)
    if (Form.ActiveForm.ActivControl != null) activeControlname = activeControl.Name;

Если не это, то я бы рассмотрел возможность написания объекта NotNullChain или FluentNotNull, который может объединить в цепочку несколько тестов на отсутствие нуля подряд. Я согласен, что метод расширения IfNotNull, действующий на null, кажется немного странным - хотя методы расширения - это просто синтаксический сахар.

Я думаю, что ответ Марка Синовца можно сделать универсальным.

IMHO, я думаю, что команда разработчиков ядра C# должна рассмотреть этот "вопрос", хотя я думаю, что есть вещи поважнее.

0
ответ дан 27 November 2019 в 15:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: