[C# 문법] C# LINQ First, FirstOrDefault, Single, SingleOrDefault 차이점
- C#/C# 문법
- 2021. 8. 24. 18:17
참고
소개
- 오늘은 C# LINQ 구문에서 First, FirstOrDefault, Single, SingleOrDefault 에 대한 차이점을 알려 드리려고 합니다.
- 많은 사람들이 LINQ를 사용하면서 위의 구문들을 사용하기는 하지만, 어떠한 차이점이 있는지에 대해서는 완벽히 숙지하지 않고 사용하는 분들이 많은 것 같고, 저 또한 그랬기에 정리할 겸 차이를 설명해 드리도록 하겠습니다.
First() 메서드
- 시퀀스의 첫 번째 요소를 반환합니다.
- 결과에 요소가 없거나 소스가 null인 경우 오류가 발생합니다.
- 둘 이상의 요소가 예상되면, 첫 번째 요소만 원하는 경우에 사용합니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp7
{
static class Program
{
static void Main(string[] args)
{
var result = InitialStudent().First();
Console.WriteLine($"{result.Name} : {result.Age} : {result.Grade} : {result.Score}");
var result2 = InitialStudent().First(x => x.Name == "범범조조2");
}
static List<Student> InitialStudent()
{
List<Student> list = new List<Student>()
{
new Student() { Name = "범범조조", Age = 20, Grade = "A", Score = 100 },
new Student() { Name = "유재석", Age = 21, Grade = "B", Score = 10 },
new Student() { Name = "김종국", Age = 22, Grade = "C", Score = 89 },
new Student() { Name = "송지효", Age = 20, Grade = "D", Score = 60 },
new Student() { Name = "하하", Age = 20, Grade = "A+", Score = 20 },
new Student() { Name = "지석진", Age = 40, Grade = "F", Score = 55 },
new Student() { Name = "아이유", Age = 30, Grade = "A", Score = 64 },
new Student() { Name = "정형돈", Age = 20, Grade = "A", Score = 79 },
new Student() { Name = "김성주", Age = 20, Grade = "A", Score = 29 }
};
return list;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Grade { get; set; }
public int Score { get; set; }
}
}
실행 결과
범범조조 : 20 : A : 100
Unhandled exception. System.InvalidOperationException: Sequence contains no matching element
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
at ConsoleApp7.Program.Main(String[] args) in C:\Users\상아\source\repos\ConsoleApp7\ConsoleApp7\Program.cs:line 15
- First() 메서드를 사용시, 해당 비교값이 없다면 위의 결과와 같이 오류가 발생합니다.
FirstOrDefalut 메서드
- 시퀀스의 첫 번째 요소를 반환하거나 요소가 없으면 기본값을 반환합니다.
- 소스가 null인 경우에만 오류가 발생합니다.
- 둘 이상의 요소가 예상되고 첫 번째 요소만 원하는 경우에 사용해야 합니다.
- 결과가 비어 있어도 좋습니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp7
{
static class Program
{
static void Main(string[] args)
{
var result = InitialStudent().FirstOrDefault();
Console.WriteLine($"{result.Name} : {result.Age} : {result.Grade} : {result.Score}");
var result2 = InitialStudent().FirstOrDefault(x => x.Name == "범범조조2");
}
static List<Student> InitialStudent()
{
List<Student> list = new List<Student>()
{
new Student() { Name = "범범조조", Age = 20, Grade = "A", Score = 100 },
new Student() { Name = "유재석", Age = 21, Grade = "B", Score = 10 },
new Student() { Name = "김종국", Age = 22, Grade = "C", Score = 89 },
new Student() { Name = "송지효", Age = 20, Grade = "D", Score = 60 },
new Student() { Name = "하하", Age = 20, Grade = "A+", Score = 20 },
new Student() { Name = "지석진", Age = 40, Grade = "F", Score = 55 },
new Student() { Name = "아이유", Age = 30, Grade = "A", Score = 64 },
new Student() { Name = "정형돈", Age = 20, Grade = "A", Score = 79 },
new Student() { Name = "김성주", Age = 20, Grade = "A", Score = 29 }
};
return list;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Grade { get; set; }
public int Score { get; set; }
}
}
실행 결과
범범조조 : 20 : A : 100
- 오류가 발생하지 않지만, Student의 기본값을 반환합니다.
Single() 메서드
- 시퀀스의 유일한 항목을 반환합니다.
- 결과에 0개 이상의 요소가 포함된 경우 예외가 발생합니다.
- 정확히 하나의 요소가 예상되지만 0이나 2 또는 그 이상이 아닌 것을 알고 있을 때 사용해야 합니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp7
{
static class Program
{
static void Main(string[] args)
{
var result2 = InitialStudent().Single(x => x.Score == 100);
Console.WriteLine($"{result2.Name} : {result2.Age} : {result2.Grade} : {result2.Score}");
var result = InitialStudent().Single(x => x.Age == 20);
Console.WriteLine($"{result.Name} : {result.Age} : {result.Grade} : {result.Score}");
}
static List<Student> InitialStudent()
{
List<Student> list = new List<Student>()
{
new Student() { Name = "범범조조", Age = 20, Grade = "A", Score = 100 },
new Student() { Name = "유재석", Age = 21, Grade = "B", Score = 10 },
new Student() { Name = "김종국", Age = 22, Grade = "C", Score = 89 },
new Student() { Name = "송지효", Age = 20, Grade = "D", Score = 60 },
new Student() { Name = "하하", Age = 20, Grade = "A+", Score = 20 },
new Student() { Name = "지석진", Age = 40, Grade = "F", Score = 55 },
new Student() { Name = "아이유", Age = 30, Grade = "A", Score = 64 },
new Student() { Name = "정형돈", Age = 20, Grade = "A", Score = 79 },
new Student() { Name = "김성주", Age = 20, Grade = "A", Score = 29 }
};
return list;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Grade { get; set; }
public int Score { get; set; }
}
}
실행 결과
범범조조 : 20 : A : 100
Unhandled exception. System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at ConsoleApp7.Program.Main(String[] args) in C:\Users\상아\source\repos\ConsoleApp7\ConsoleApp7\Program.cs:line 15
- 같은게 2개 이상 존재하면 Single() 메서드에서는 에러가 발생합니다.
SingleOrDefault() 메서드
- 하나의 특정 요소를 반환하고 요소를 찾지 못하면 기본값을 반환합니다.
- 결과에 2개 이상의 요소가 포함된 경우 예외가 발생합니다.
- 결과로 0 또는 1개의 요소가 예상된다는 것을 알 때 사용해야 합니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp7
{
static class Program
{
static void Main(string[] args)
{
var result2 = InitialStudent().SingleOrDefault(x => x.Score == 100);
Console.WriteLine($"{result2.Name} : {result2.Age} : {result2.Grade} : {result2.Score}");
var result = InitialStudent().SingleOrDefault(x => x.Age == 33);
}
static List<Student> InitialStudent()
{
List<Student> list = new List<Student>()
{
new Student() { Name = "범범조조", Age = 20, Grade = "A", Score = 100 },
new Student() { Name = "유재석", Age = 21, Grade = "B", Score = 10 },
new Student() { Name = "김종국", Age = 22, Grade = "C", Score = 89 },
new Student() { Name = "송지효", Age = 20, Grade = "D", Score = 60 },
new Student() { Name = "하하", Age = 20, Grade = "A+", Score = 20 },
new Student() { Name = "지석진", Age = 40, Grade = "F", Score = 55 },
new Student() { Name = "아이유", Age = 30, Grade = "A", Score = 64 },
new Student() { Name = "정형돈", Age = 22, Grade = "A", Score = 79 },
new Student() { Name = "김성주", Age = 20, Grade = "A", Score = 29 }
};
return list;
}
}
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Grade { get; set; }
public int Score { get; set; }
}
}
실행 결과
범범조조 : 20 : A : 100
- 현재 나이가 33인 학생은 없지만, 예외가 발생하지 않는 것을 확인할 수 있습니다.
정리
- 예외처리 신경쓰고 싶다면, FirstOrDefault, SingleOrDefault를 사용하는걸 추천 드립니다.
728x90
'C# > C# 문법' 카테고리의 다른 글
[C# 문법] C# LINQ Take, TakeWhile 메서드 (0) | 2021.08.28 |
---|---|
[C# 문법] C# LINQ 형변환 OfType<T> 메서드 (0) | 2021.08.25 |
[C# 문법] C# LINQ FirstOrDefault, LastOrDefault 메서드 (0) | 2021.08.22 |
[C# 문법] C# LINQ SequenceEqual 메서드 (0) | 2021.08.22 |
[C# 문법] C# LINQ Count 메서드 (0) | 2021.08.22 |
이 글을 공유하기