다음을 통해 공유


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 properties를 사용하여 명명된 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);

쿼리 myQuery1 는 다음 foreach 루프에서 실행됩니다.

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);
}