Royi Namir
Royi Namir

Reputation: 148524

Linq's FirstOrDefault to act as other type?

I have this code :

var res1 = dtData.AsEnumerable()
            .Where(...)
            .Select(f => new { val = f["PremiumAfterUWDiscount"].ToDecimalOrZero(), 
                   idpolicy = f["IdPolicy"].ToString() })
            .FirstOrDefault();

however , since this returns an anonymous type , its default value is null .

I want it to act as FirstOrDefault for int type.

so if there is no record , it will return 0 ( default behavior as int).

is it possible ?

p.s. ( of course i can check it in a condition but still , i prefer the linq way).

Upvotes: 2

Views: 4617

Answers (3)

Adam Houldsworth
Adam Houldsworth

Reputation: 64477

Return an anonymous type that signifies "nothing" and either use the null coalescing operator:

var res1 = dtData.AsEnumerable()
        .Where(...)
        .Select(f => new { val = f["PremiumAfterUWDiscount"].ToDecimalOrZero(), 
               idpolicy = f["IdPolicy"].ToString() })
        .FirstOrDefault() ?? new { val = 0, idpolicy = "" };

Or the DefaultIfEmpty extension method:

var res1 = dtData.AsEnumerable()
        .Where(...)
        .Select(f => new { val = f["PremiumAfterUWDiscount"].ToDecimalOrZero(), 
               idpolicy = f["IdPolicy"].ToString() })
        .DefaultIfEmpty(new { val = 0, idpolicy = "" })
        .FirstOrDefault();

You would only be able to return an int in place of an anonymous type if you in fact return an object and cast later on (as per @recursive's answer), but this to me seems counter-productive.

FirstOrDefault does not offer a way to specify what "default" is.

Upvotes: 2

recursive
recursive

Reputation: 86064

Doing this doesn't make any sense, and I would encourage you to think about why you want to do this, and find some cleaner, more direct way to accomplish it.

With that said, here's a small tweak to @IronicMuffin's approach that will actually work.

object res1 = dtData.AsEnumerable()
    .Where(...)
    .Select(f => new { 
        val = f["PremiumAfterUWDiscount"].ToDecimalOrZero(), 
        idpolicy = f["IdPolicy"].ToString() 
    })
    .FirstOrDefault() as object ?? 0;

I don't think this is very useful though.

Upvotes: 1

linkerro
linkerro

Reputation: 5458

You can't have an expression evaluate to 2 different data types on two execution paths. Also, even if that's possible, var is different to dynamic so the variable type won't be inferred by the compiler.

Upvotes: 1

Related Questions