Ярлык для «null, если объект равен нулю, или object.member, если объект не равен нулю» [duplicate]

На этот вопрос уже есть ответ здесь:

Глубокая проверка нуля, есть ли лучший способ? 16 ответовКак проверить наличие нулей в глубоком лямбда-выражении? [Дубликат] 10 ответов

Я пытаюсь написать общий метод расширения, который позволяет мне сделать это:

this.startDate = startDateXAttribute.NullOrPropertyOf<DateTime>(() =>
{
    return DateTime.Parse(startDateXAttribute.Value);
});

NullOrPropertyOf() вернетсяnull если он используется наnull объект (например, еслиstartDateXAttribute былоnull) или вернуть результатFunc если это не ноль.

Как бы выглядел этот метод расширения?

 stakx30 июл. 2014 г., 15:40
На данный момент такая функция фактически запланирована для C # 6: см.Платформа компилятора .NET ("Roslyn"): Состояние функции языка: Нуль-оператор распространения?.
 Judah Gabriel Himango29 сент. 2010 г., 18:51
Примечание для разработчиков языка C #: добавление в язык чего-то вроде безобидного оператора разыменования, вероятно, будет популярной функцией. :-)
 Judah Gabriel Himango29 сент. 2010 г., 18:49
 Hawxby05 мар. 2014 г., 14:41
 Judah Gabriel Himango29 сент. 2010 г., 18:49

Ответы на вопрос(3)

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

public static class Extension
{
    public static T NullOrPropertyOf<T>(this XAttribute attribute, Func<string, T> converter)
    {
        if (attribute == null)
        {
            return default(T);
        }
        return converter.Invoke(attribute.Value);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Func<string, DateTime?> convertDT = (string str) =>
        {
            DateTime datetime;
            if (DateTime.TryParse(str, out datetime))
            {
                return datetime;
            }
            return null;
        };
        Func<string, string> convertStr = (string str) =>
        {
            return str;
        };
        XAttribute x = null;
        Console.WriteLine(x.NullOrPropertyOf<string>(convertStr));
        Console.WriteLine(x.NullOrPropertyOf<DateTime?>(convertDT));
        XName t = "testing";
        x = new XAttribute(t, "test");
        Console.WriteLine(x.NullOrPropertyOf<string>(convertStr));
        x = new XAttribute(t, DateTime.Now);
        Console.WriteLine(x.NullOrPropertyOf<DateTime?>(convertDT));
    }
}
 nawfal10 окт. 2013 г., 08:35
Вам не нужно указывать тип параметра лямбда, когда вы записываете тип в lhs.
Решение Вопроса

его реализация - довольно часто запрашиваемая функция. Синтаксис может быть что-то вроде:

x = foo.?bar.?baz;

То есть, x равно нулю, если foo или foo.bar равны нулю, и результат foo.bar.baz, если ни один из них не равен нулю.

Мы рассматривали это для C # 4, но это не сделало это где-нибудь в верхней части списка приоритетов. Мы будем иметь это в виду для гипотетических будущих версий языка.

ОБНОВЛЕНИЕ: C # 6 будет иметь эту функцию. Увидетьhttp://roslyn.codeplex.com/discussions/540883 для обсуждения конструктивных соображений.

 Eric Lippert15 окт. 2013 г., 16:36
@nawfal: Отличная мысль.
 Matti Virkkunen07 июн. 2012 г., 01:19
@Eric: поздравляю. Ты говоришь как юрист!
 nawfal19 окт. 2013 г., 08:56
@EricLippert Nemerle делает то же самое!
 Eric Lippert29 сент. 2010 г., 16:08
@vc: Я напоминаю вам, что размышления Эрика о гипотетических особенностях необъявленных будущих продуктов, которые не существуют сегодня и могут никогда не существовать,только для развлекательных целей и не дают никаких обещаний доставить какой-либо продукт с какой-либо функцией в любое время.
 vc 7429 сент. 2010 г., 18:00
ты мое определение для осторожных
 Jeppe Stig Nielsen03 мая 2014 г., 08:43
Обновление: вклРослин список языковых особенностей этот пункт "запланирован". Кажется, они используют?. и не.?.
 vc 7429 сент. 2010 г., 08:58
гипотетическая? Я надеюсь, что MS не собирается бросать C # так скоро;)
 nawfal15 окт. 2013 г., 12:03
@EricLippert не будет?. будь лучше? Первый стиль вопросительного знака больше соответствует семантике троичного оператора (что больше похоже на проверку условия), а затем завершающему периоду. открывает область действия intellisense и выводит список всех существующих участников. Мой выбор:x = foo?.bar?.baz;
 Eric Lippert13 февр. 2015 г., 17:50
@Matt: C # 6 будет иметь эту функцию. Увидетьroslyn.codeplex.com/discussions/540883
 Matt13 февр. 2015 г., 12:44
«оператор безопасной навигации» ?. (напримерvar x = a?.b?.c?.d;) упомянутоВот на MSDN он получил 3752 голоса на голос пользователя. Надеюсь, это будет реализовано в ближайшее время, так как эквивалентvar x=(a==null)?null:((b==null)?null:((c==null)?null:a.b.c.d)); простоUGLY.

Класс XAttribute обеспечиваетоператор явного преобразования за это:


DateTime? result = (DateTime?)startDateXAttribute;

Для общего случая, лучший вариант, вероятно, такой:

DateTime? result = (obj != null) ? (DateTime?)obj.DateTimeValue : null;

Ваш ответ на вопрос