다음을 통해 공유


LINQ를 지원하는 C# 기능

쿼리 식

쿼리 식은 SQL 또는 XQuery와 유사한 선언적 구문을 사용하여 System.Collections.Generic.IEnumerable<T> 컬렉션을 쿼리합니다. 컴파일 시 컴파일러는 쿼리 구문을 메서드 호출로 변환하여 LINQ 공급자의 표준 쿼리 메서드 구현으로 변환합니다. 애플리케이션은 지시문을 사용하여 적절한 네임스페이스를 지정하여 범위에 있는 표준 쿼리 연산자를 using 제어합니다. 다음 쿼리 식은 문자열 배열을 사용하여 문자열의 첫 번째 문자에 따라 그룹화하고 그룹을 정렬합니다.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

암시적으로 형식화된 변수(var)

var 한정자를 사용하여 다음과 같이 형식을 유추하고 할당하도록 컴파일러에 지시할 수 있습니다.

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

변수는 var로 선언되어 형식을 명시적으로 지정한 변수처럼 강력한 형식을 가집니다. 사용하면 var 익명 형식을 만들 수 있지만 지역 변수에 대해서만 만들 수 있습니다. 자세한 내용은 암시적으로 형식화된 지역 변수를 참조하세요.

개체 및 컬렉션 이니셜라이저

개체 및 컬렉션 이니셜라이저를 사용하면 개체에 대한 생성자를 명시적으로 호출하지 않고도 개체를 초기화할 수 있습니다. 일반적으로 쿼리 식에서 원본 데이터를 새 데이터 형식으로 프로젝션할 때 이니셜라이저를 사용합니다. public CustomerName 속성으로 명명된 Phone 클래스를 가정하면 다음 코드와 같이 개체 이니셜라이저를 사용할 수 있습니다.

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

당신의 Customer 클래스를 계속 진행하면서, IncomingOrders라는 데이터 원본이 있다고 가정하고, 크기가 큰 OrderSize이 있는 각 주문에 대해 해당 주문을 기반으로 새 Customer를 만들려고 합니다. 이 데이터 원본에서 LINQ 쿼리를 실행하고 개체 초기화를 사용하여 컬렉션을 채울 수 있습니다.

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

데이터 원본에는 Customer 클래스와 OrderSize 같이 정의된 속성이 더 많이 포함될 수 있습니다. 하지만 개체 초기화를 사용하여 쿼리에서 반환된 데이터를 원하는 데이터 형식으로 변환할 수 있습니다. 이렇게 하면 클래스와 관련된 데이터를 선택할 수 있습니다. 결과적으로, 이제 System.Collections.Generic.IEnumerable<T> 원하는 새 Customer항목으로 채워집니다. LINQ의 메서드 구문에서 앞의 예제를 작성할 수도 있습니다.

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

C# 12부터 컬렉션 식을 사용하여 컬렉션을 초기화할 수 있습니다.

자세한 내용은 다음을 참조하세요.

무명 형식

컴파일러는 익명 형식을 생성합니다. 컴파일러만 형식 이름에 액세스할 수 있습니다. 익명 형식은 별도의 명명된 형식을 정의하지 않고도 쿼리 결과에서 속성 집합을 일시적으로 그룹화할 수 있는 편리한 방법을 제공합니다. 다음과 같이 새 식 및 개체 이니셜라이저를 사용하여 무명 형식을 초기화합니다.

select new {name = cust.Name, phone = cust.Phone};

C# 7부터 튜플을 사용하여 명명되지 않은 형식을 만들 수 있습니다.

확장 멤버

확장 멤버수신기 형식이라는 형식과 연결된 정적 클래스의 정적 멤버입니다. 확장 멤버는 수신기 유형의 멤버인 것처럼 호출할 수 있습니다. 이 기능을 사용하면 새 멤버를 실제로 수정하지 않고 기존 형식에 "추가"할 수 있습니다. 표준 쿼리 연산자는 구현하는 모든 형식에 대해 LINQ 쿼리 기능을 제공하는 확장 메서드 집합입니다 IEnumerable<T>.

람다 식

람다 식은 연산자를 사용하여 => 함수 본문에서 입력 매개 변수를 분리하고 컴파일 시간에 대리자 또는 식 트리로 변환할 수 있는 인라인 함수입니다. LINQ 프로그래밍에서는 표준 쿼리 연산자를 직접 메서드로 호출할 때 람다 식이 발생합니다.

데이터로서의 표현식

쿼리 개체는 작성할 수 있으므로 메서드에서 쿼리를 반환할 수 있습니다. 쿼리를 나타내는 개체는 결과 컬렉션을 저장하지 않고 필요한 경우 결과를 생성하는 단계입니다. 메서드에서 쿼리 개체를 반환하는 장점은 추가로 작성하거나 수정할 수 있다는 것입니다. 따라서 쿼리를 반환하는 메서드의 반환 값 또는 out 매개 변수에도 해당 형식이 있어야 합니다. 메서드가 쿼리를 구체적 List<T> 또는 Array 형식으로 구체화하는 경우 쿼리 자체 대신 쿼리 결과를 반환합니다. 메서드에서 반환된 쿼리 변수를 작성하거나 수정할 수 있습니다.

다음 예제에서 첫 번째 메서드 QueryMethod1 는 쿼리를 반환 값으로 반환하고 두 번째 메서드 QueryMethod2 는 쿼리를 out 매개 변수로 반환합니다(returnQ 예제에서). 두 경우 모두 쿼리 결과가 아니라 반환되는 쿼리입니다.

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ = from i in ints
              where i < 4
              select i.ToString();

int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var myQuery1 = QueryMethod1(nums);

다음 foreach 루프는 쿼리 myQuery1를 실행합니다.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

마우스 포인터를 놓아 myQuery1 형식을 확인합니다.

QueryMethod1를 사용하지 않고 myQuery1에서 직접 반환된 쿼리를 실행할 수도 있습니다.

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

마우스 포인터를 호출 QueryMethod1 위에 놓아 반환 형식을 확인합니다.

QueryMethod2 는 쿼리를 해당 매개 변수의 값으로 반환합니다 out .

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

쿼리 컴퍼지션을 사용하여 쿼리를 수정할 수 있습니다. 이 경우 이전 쿼리 개체를 사용하여 새 쿼리 개체를 만듭니다. 이 새 개체는 원래 쿼리 개체와 다른 결과를 반환합니다.

myQuery1 = from item in myQuery1
           orderby item descending
           select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}