Question

I am using LINQ in an MVC app. I have noticed I can create a method in 2 ways, both work but I dont know which is best.

Direct:

public string GetStatus(int PersonId)
{
    return db.PersonStatus
        .Where(x => x.personid == PersonId)
        .Select(x => x.Status)
        .Single();
}

In a var first:

public string GetStatus(int PersonId)
{
    string Item = db.PersonStatus
        .Where(x => x.personid == PersonId)
        .Select(x => x.Status)
        .Single();
    return Item;
}

I prefer the first, direct method as it seems more efficient. Please let me know if there is a significant difference between the two, and if so, what?

Était-ce utile?

La solution

To the best of my knowledge, there is no practical difference between the two (and the second might get optimized to the first). There's also no difference between doing this with LINQ and with a regular function.

However, the second one will be easier to debug, because you're putting the result somewhere after evaluating it, so you can put a breakpoint in and examine that variable. I find the first marginally clearer, though.


Here's two functions:

int Foo(int a, int b)
{
    int x = a+b;
    return x;
}

int Bar(int a, int b)
{
    return a+b;
}

And here's the IL that's generated with optimizations off (according to LINQPad):

Foo:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.2     
IL_0003:  add         
IL_0004:  stloc.0     // x
IL_0005:  ldloc.0     // x
IL_0006:  stloc.1     // CS$1$0000
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.1     // CS$1$0000
IL_000A:  ret         

Bar:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.2     
IL_0003:  add         
IL_0004:  stloc.0     // CS$1$0000
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.0     // CS$1$0000
IL_0008:  ret         

You'll notice that Foo has two extra lines where it declares the variable then reads it.

And here it is with optimizations on:

Foo:
IL_0000:  ldarg.1     
IL_0001:  ldarg.2     
IL_0002:  add         
IL_0003:  stloc.0     // x
IL_0004:  ldloc.0     // x
IL_0005:  ret         

Bar:
IL_0000:  ldarg.1     
IL_0001:  ldarg.2     
IL_0002:  add         
IL_0003:  ret    

Again, one extra assignment and load. You'll never notice the difference.

Autres conseils

There is no difference (I imagine this will get optimised down to end up exactly the same when it is executed).

The first option is more concise, the latter gives you an obvious breakpoint, and ease of inserting more code working with your query if you later decide to. That said, it's pretty easy to add in in that case. Just go with whatever reads best to you.

No significant difference. I like the first one better, although it may be easier to debug if you use the second one, so you could see what you are returning. Also, if you are likely to need to make some changes to what you return, you will probably end up moving to the second way.

There is no difference. I prefer the first unless I'm debugging and want to watch the result.

Be careful with the first option if your function returns IQueryable<T>, though, as the result won't actually be evaluated until the calling function iterates the queryable. This can lead to weird bugs if you're using closures and things (where the runtime will try to evaluate the queryable after it's context has gone away).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top