Nice programing

확장 메서드 구문과 쿼리 구문

nicepro 2020. 11. 18. 21:29
반응형

확장 메서드 구문과 쿼리 구문


표준 linq 키워드 또는 linq 확장 메서드를 람다 식과 함께 사용할 좋은 시간이 있는지 확인하려고합니다. 그들은 똑같은 일을하는 것 같지만 다르게 쓰여졌습니다. 순전히 스타일의 문제입니까?

var query = from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p;

// or with extension methods:
var query = Products
    .Where(p => p.Name.Contains("foo"))
    .OrderBy(p => p.Name);

두 번째 예는 좀 더 간결하지만 =>가 무엇을하는지 모르는 경우 표현력이 떨어집니다.

간결한 코드를 작성하는 것 외에 LINQ 구문과 달리 확장 메서드를 사용하면 다른 이점이 있습니까?


솔직히, Funcs 및 Actions를 사용하기 시작하면 상황에 따라 달라질 수 있습니다. 다음 세 가지 기능을 사용하고 있다고 가정합니다.

  Func<DataClasses.User, String> userName = user => user.UserName;
  Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
  Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

보시다시피 첫 번째는 사용자 이름을 얻기 위해 lamdba 표현식을 대체하고, 두 번째는 ID가 10 미만인지 확인하는 데 사용되는 lamdba 표현식을 대체하고, 직면 해 봅시다. 세 번째는 이제 매우 이해하기 쉽습니다.

참고 : 이것은 어리석은 예이지만 작동합니다.

  var userList = 
    from user in userList
    where userIDOverTen(user)
    select userName;

  var otherList =
    userList
    .Where(IDIsBelowNumber)
    .Select(userName)

이 예제에서 두 번째는 확장 메서드가 Func를 최대한 활용할 수 있기 때문에 약간 덜 장황하지만 Linq 표현식은 부울을 반환하는 Func가 아닌 부울을 찾기 때문에 불가능합니다. 그러나 이것은 표현 언어를 사용하는 것이 더 나은 곳입니다. 사용자 이상의 기능을 사용하는 방법이 이미 있다고 가정 해 보겠습니다.

  private Boolean IDIsBelowNumber(DataClasses.User user, 
          Int32 someNumber, Boolean doSomething)
  {
    return user.UserID < someNumber;
  }

참고 : doSomething은 사용자와 정수를 받아들이고 부울을 반환하는 메서드와 함께 where 확장 메서드가 괜찮 기 때문에 거기에 있습니다. 이 예에서는 다소 짜증이납니다.

이제 Linq 쿼리를 보면 :

  var completeList =
     from user in userList
     where IDIsBelowNumber(user, 10, true)
     select userName;

당신은 그것을 잘합니다. 이제 확장 방법 :

  var otherList =
    userList
    .Where(IDIsBelowNumber????)
    .Select(userName)

람다식이 없으면이 메서드를 호출 할 수 없습니다. 이제 제가해야 할 일은 원래의 메서드 호출을 기반으로 Func를 만드는 메서드를 만드는 것입니다.

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
   {
      return user => IDIsBelowNumber(user, number, true);
   }

그런 다음 연결합니다.

  var otherList =
     userList
     .Where(IDIsBelowNumberFunc(10))
     .Select(userName)

따라서 때때로 쿼리 접근 방식을 사용하는 것이 더 쉬울 수 있습니다.


LINQ 확장 메서드 ( 메서드 기반 쿼리 ) 를 사용할 때의 한 가지 이점 은 사용자 지정 확장 메서드를 정의 할 수 있으며 여전히 잘 읽을 수 있다는 것입니다.

반면에 LINQ 쿼리 식을 사용하는 경우 사용자 지정 확장 메서드가 키워드 목록에 없습니다. 다른 키워드와 섞여서 조금 이상하게 보일 것입니다.

Into문자열 만 받는 사용자 지정 확장 메서드를 사용하고 있습니다 .

쿼리가있는 예

var query = (from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p).Into("MyTable");

Example with extension methods

var query = Products
                   .Where(p => p.Name.Contains("foo"))
                   .OrderBy(p => p.Name)
                   .Into("MyTable");

In my opinion the latter, using a method-based query, reads better when you have custom extension methods.


I think it's a good idea not to use them together and choose one and stick with it.

Mostly it's personal taste, but in the query syntax (Comprehension method) not all operators are available as was said before.

I find the Extension Methods syntax more in line with the rest of my code. I do my SQL in SQL. It's also very easy to build your expression just by adding everything on top of eachother with the extension methods.

Just my two cents.

As I cannot make comments yet I want to make one here to the answer of Programming Tool: Why make a whole new method for the last example?? Can't you just use:

.Where(user => IDIsBelowNumber(user, 10, true))


They compile the same, and are equivalent. Personally, I prefer the lambda (extension) methods for most things, only using the statements (standard) if I'm doing LINQ to SQL or otherwise trying to emulate SQL. I find that the lambda methods flow better with code, whereas the statements are visually distracting.


I prefer the extension method syntax when I use Linq methods that have no query syntax equivalent, such as FirstOrDefault() or others like that.


I like to use the query syntax when its really a query, ie a lazy expression which evaluates on demand.

A method that looks like regular method calls (method syntax or the lambda syntax) doesn't look lazy enough, so I use that as a convention. For eg,

var query = from p in Products
            where p.Name.Contains("foo")
            orderby p.Name
            select p;

var result = query.ToList(); //extension method syntax

If it's a not a query, I like the fluent style which looks to me consistent with other eagerly executing calls.

var nonQuery = Products.Where(p => p.Name.Contains("foo"))
                       .OrderBy(p => p.Name)
                       .ToList();

It helps me to differentiate the two styles of calls better. Of course there are situations where you will be forced to use method syntax anyway, so my convention is not very compelling enough.


One advantage of extension methods/lynda expressions is the additional operators that is offered like Skip and Take. For example, if you are creating a pagination method, being able to skip the first 10 records and take the next 10 is easy to implement.

참고URL : https://stackoverflow.com/questions/279701/extension-methods-syntax-vs-query-syntax

반응형