Ярлык для "ноль, если объект нуль, или object.member, если объект не нуль"
Я пытаюсь написать общий метод расширения, который позволяет мне сделать это:
this.startDate = startDateXAttribute.NullOrPropertyOf<DateTime>(() =>
{
return DateTime.Parse(startDateXAttribute.Value);
});
NullOrPropertyOf()
вернется null
если он используется на null
объект (например, если startDateXAttribute
было null
) или вернуть результат Func
если это не ноль.
Как бы выглядел этот метод расширения?
3 ответа
Там нет краткой формы для этого; его реализация - довольно часто запрашиваемая функция. Синтаксис может быть что-то вроде:
x = foo.?bar.?baz;
То есть, x равно нулю, если foo или foo.bar равны нулю, и результат foo.bar.baz, если ни один из них не равен нулю.
Мы рассматривали это для C# 4, но это не сделало это где-нибудь в верхней части списка приоритетов. Мы будем иметь это в виду для гипотетических будущих версий языка.
ОБНОВЛЕНИЕ: C# 6 будет иметь эту функцию. См. http://roslyn.codeplex.com/discussions/540883 для обсуждения конструктивных соображений.
Класс XAttribute предоставляет явный оператор преобразования для этого:
XAttribute startDateXAttribute = // ...
DateTime? result = (DateTime?)startDateXAttribute;
Для общего случая, лучший вариант, вероятно, такой:
DateTime? result = (obj != null) ? (DateTime?)obj.DateTimeValue : null;
Это то, что вы ищете? Я думаю, что он сломается, если вы передадите необнуляемый тип значения, но он должен работать, когда вы используете обнуляемые типы. Пожалуйста, дайте мне знать, если я что-то упустил.
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));
}
}