views:

226

answers:

3

I was wondering, after having read this question... he has this code:

public static T FindOrCreate<T>(this Table<T> table, Func<T, bool> find) 
    where T : new()
{
    T val = table.FirstOrDefault(find);
    if (val == null)
    {
        val = new T();
        table.InsertOnSubmit(val);
    }
    return val;
}

Would it be possible to also send in that new item as another Func? I mean, of course it would. But, would that have been created already? Or would it be created first when you actually run the Func? Lets say you have this:

public static T FindOrCreate<T>(this Table<T> table, Func<T, bool> find, Func<T> replacement) 
    where T : new()
{
    T val = table.FirstOrDefault(find);
    if (val == null)
    {
        val = replacement();
        table.InsertOnSubmit(val);
    }
    return val;
}

And then called that by doing this:

var invoiceDb = ctx.Invoices.FindOrCreate(a => a.InvoicerId == InvoicerId
                                            && a.Number == invoiceNumber,
                                          () => new Invoice());
invoiceDb.Number = invoiceNumber;

If that invoice was found, would that new Invoice have been created? Or is that code ran not until the function is actually called? or how does that work?

+1  A: 

The code in replacement wouldn't be run until the function was actually called, and the value was found to be missing in the table.

By the way, if you implement this as stated, which is perfectly reasonable -- you might want to remove the "where T : new()" constraint from the function, since it's no longer necessary; you give it all the information about how to construct one quite explicitly.

mquander
that is also true. I just copy pasted the code from his answer, didn't really think much about it :p
Svish
+1  A: 

In this case you're passing a delegate so the

() => new Invoice()

code is not called until the

val = replacement();

line

Steve Willcock
A: 

No, the new invoice would not have been created. Func is just a delegate, so when you're creating the lambda: () => new Invoice() it's virtually the same as doing this:

public Invoice Create()
{
   return new Invoice();
}

and passing in a delegate to the Create method. Only once you actually execute the delegate (the "create" function) does that code actually run and thus the invoice get created.

BFree