views:

230

answers:

3

I'm trying to write a generic extension method that let's me do this:

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

NullOrPropertyOf() would return null if it's used on a null object (e.g. if startDateXAttribute was null), or return the result of a Func if it's not null.

What would this extension method look like?

+1  A: 

The XAttribute Class provides an explicit conversion operator for this:

XAttribute startDateXAttribute = // ...

DateTime? result = (DateTime?)startDateXAttribute;

For the general case, the best option is probably this:

DateTime? result = (obj != null) ? (DateTime?)obj.DateTimeValue : null;
dtb
+6  A: 

There's no short form for that; implementing one is a fairly frequently requested feature. The syntax could be something like:

x = foo.?bar.?baz;

That is, x is null if foo or foo.bar are null, and the result of foo.bar.baz if none of them are null.

We considered it for C# 4 but it did not make it anywhere near the top of the priority list. We'll keep it in mind for hypothetical future versions of the language.

Eric Lippert
hypothetical? I hope MS is not going to drop C# so soon ;)
vc 74
@vc: I remind you all that Eric's musings about hypothetical features of unannounced future products that do not exist today and might never exist are *for entertainment purposes only* and do not constitute any promise to deliver any product with any feature at any time.
Eric Lippert
@Eric: you're my definition for cautious
vc 74
A: 

Is this what you're looking for? I think it breaks down if you pass a non-nullable value type, but it should work when you're using nullable types. Please let me know if there is something I've overlooked.

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));
    }
}
s_hewitt