-
[프렉티컬 C# 연습문제] 2부 - 1장Development/C# 2023. 7. 25. 01:16728x90
관용구
1. 변수,배열,리스트,객체 선언과 초기화는 동시에 이뤄져야 하는 것이 원칙
// 변수 var age = 25; // 배열, 리스트 // 마지막 요소 뒤에 콤마 붙이면 요소를 바꾸거나 추가할 때 편함 var langs = new string[] {"C#", "VB", "C++",}; var nums = new List<int> {10,20,30,40,}; // Dictionary var dict = new Dictionary<string, string>() { {"ko", "한국어"}, {"en", "영어"}, {"es", "스페인어"} }; // or after C# 6.0 var dict = new Dictionary<string, string>() { ["ko"] = "한국어", ["en"] = "영어", ["es"] = "스페인어" }; // 객체 var person = new Person { Name = "", Birthday = new DateTime(1995, 11, 23), PhoneNumber = "012-3456-7890", };
2. 비교하려는 변수는 비교 연산자의 왼쪽에 두기
if(a < 10) is good,
if(10 > a) is bad
3. 범위에 해당 수치가 있는지 조사할 때는 변수는 가운데 두기
if(a <= num && num <= b) is good,
if(num >= a && num <= b) is bad
4. 체로 걸러 남은 것만 처리
return문에는 메서드의 실행을 중단시키고 호출하는 쪽에 제어를 돌려주는 기능이 있다.
// good code if (a == null) return; if (Kale() == Apple.Skip) return; if (targetType != originalType) return; // bad code if (a != null){ if (Kale() != Apple.Skip) { if (targetType == originalType) { .... } } }
5. 반드시 1부터 시작해야 할 경우가 아니라면 n번 반복할 때는 루프 변수를 0부터 시작
반복할 횟수 알면 for문 사용, 모르면 while문 사용
6. 컬렉션에서 모든 요소를 꺼낼 경우에는 for문이 아니라 foreach 사용
7. List<T> 클래스만 한정으로 ForEach 메서드 사용 가능
ForEach 메서드 안에는 한 줄에 쓸 수 있는 길이의 간단한 코드만 사용하고 여러 행으로 구성된 코드라면 foreach 사용
// 아래와 같은 코드 bad! nums.ForEach(n=> { ... ... ... });
리스트에 있는 요소를 그대로 메서드의 인수로 전달할 수 있고 반환값이 없는 메서드일 경우에는 메서드 이름만 지정 가능
nums.ForEach(Console.WriteLine);
8. null 합체 연산자(??)
// GetResult(b) 반환 값이 null 이면 DefaultResult() 호출 var a = GetResult(b) ?? DefaultResult();
9. null 조건 연산자(?.)
return sale?. Product; // 위, 아래 동일한 코드 if(sale == null) return null; else return sale.Product;
null 조건 연산자는 배열에도 사용 가능하며 배열인 경우에는 점(.) 생략 가능
var first = customers?[0];
10. 속성 초기화
// C# 6.0 이후 부터 사용 가능 public int MinimumLength {get; set;} = 6;
get 접근자 본문을 하나의 식으로 표현할 수 있는 경우 => 연산자를 사용해서 읽기 전용 속성 정의 가능
public class Person { ... public string Nmae => FamilyName + " " + GivenName; ... }
11. params 키워드
가변 인수는 받아들이는 메서드를 정의할 경우와 인수를 지정해서 로그를 출력하는 메서드를 정의할 경우 params 키워드 사용
12. 옵션 인수
인수가 생력됐을 때 초깃값이 값이 된다.
private void DoSomething(int num, string message = "실패", int retryCount = 3) { ... }
12. 축자 문자열 리터럴 / 문자열 보관
축자 문자열
문자열 앞에 @을 붙인 것를 의미
var path = @"C:\Example\Greeting.txt"; // @을 붙이지 않으면 \ 기호를 연속해서 써야함 var path = "C:\\Example\\Greeting.txt";
문자열 보관
-문자열 앞에 $을 붙인 것을 의미
-문자열 보간은 String.Format 메서드와 동일한 결과를 제공하지만 더 편리하고 인라인 명확성이 향상된다.
$"{Year}년{Month}월"; // 동일 String.Format("{0}년{1}월", Year, Month);
13. 두 개의 요소를 바꾸는 경우
// good code var temp = a; a = b; b = temp; // bad code var temp1 = a; var temp2 = b; a = temp2; b = temp1;
C# 7.0에서는 튜플을 사용해 (b a) = (a b); 가능
14. TryParse 메서드
-문자열을 숫자값으로 변환하려고 할 때 오류가 있는지 확인
-변환 성공하면 true, 실패하면 false를 반환
-확실히 숫자로만 구성되있다는 보장이 있는 경우만 parse 사용
int height; if (int.TryParse(str, out height)) { // height에는 변환된 값이 들어 있다 ... } else { ... }
15. as 연산자
참조형 객체를 다른 형으로 형변환 한다.
16. using을 사용해 리소스 정리
Dispose 메서드를 직접 호출 대신 using 문 사용하면 Dispose 메서드 자동 호출된다.
16. 여러 개의 생성자 정의
- 생성자의 인수를 쓰고 괄호를 닫고 여기에 :this(...)라고 쓰면 생성자 본문을 처리({} 안에 있는 내용)하기에 앞서 오버로드된 다른 생성자를 호출할 수 있다
class AppVersion { ... public AppVersion(int major, int minor) :this(major, minor, 0, 0){ } public AppVersion(int major, int minor, int revision) :this(major, minor, revision, 0){ } // 위에 있는 두 개의 생성자가 이 생성자를 호출한다 public AppVersion(int major, int minor, int build, int revision){ Major = major; Minor = minor; Build = build; Revision = revision; } }
C# 4.0에서는 옵션인수 사용하여 아래와 같이 작성 가능
class AppVersion { ... public AppVersion(int major, int minor, int build = 0, int revision = 0){ Major = major; Minor = minor; Build = build; Revision = revision; } ... }
17. this 키워드
this 키워드는 아래의 4가지 경우에 사용
1. 자신의 인스턴스를 참조할 때 사용
2. 인덱서를 정의할 때 사용
3. 확장 메서드의 첫 인수의 수식자로 사용
4. 한 클래스 내에서 다른 생성자를 호출할 때 사용
연습 문제
문제 4.1
using System; public class YearMonth { public int Year { get; private set; } public int Month { get; private set; } public bool Is21Centrury => 20001 <= Year && Year >= 2100; public YearMonth(int year, int month) { this.Year = year; if (1 <= month && month <= 12) { this.Month = month; } else { throw new Exception("1부터 12까지만 허용"); } } public YearMonth AddOneMonth() { DateTime resultDate = new DateTime(this.Year, this.Month, 1).AddMonths(1); YearMonth yearmonth = new YearMonth(resultDate.Year, resultDate.Month); return yearmonth; } public override string ToString() { return String.Format("{0}년 {1}월", this.Year, this.Month); } }
해설
namespace Chapter04 { // 4.1.1 public class YearMonth { public int Year { get; private set; } public int Month { get; private set; } public YearMonth(int year, int month) { Year = year; Month = month; } // 4.1.2 public bool Is21Century { get { return 2001 <= Year && Year <= 2100; } } // 4.1.3 public YearMonth AddOneMonth() { if (Month == 12) { return new YearMonth(this.Year + 1, 1); } else { return new YearMonth(this.Year, this.Month + 1); } } // 4.1.4 public override string ToString() { return $"{Year}年{Month}月"; } } }
문제 4.2
using System; using System.Linq; namespace helloworld { class Program { // 3번 static YearMonth ReturnFirst21Century(YearMonth[] array) { foreach (var item in array) { if (item.Is21Centrury) { return item; } } return null; } static void Main(string[] args) { // 1번 var array = new YearMonth[] { new YearMonth(2021, 02) , new YearMonth(2013, 12) , new YearMonth(2022, 08) , new YearMonth(2024, 05) , new YearMonth(2003, 10), }; // 2번 foreach (var item in array) { Console.WriteLine("{0},{1},{2}", item.Year, item.Month, item.Is21Centrury); } // 4번 var result = ReturnFirst21Century(array); Console.WriteLine(result?.Year.ToString() ?? "21세기 데이터는 없습니다."); // 5번 var newArray = array.Select(s => new DateTime(s.Year, s.Month, 1).AddMonths(1)).ToArray(); } } }
해설
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Chapter04; namespace Exercise2 { class Program { static void Main(string[] args) { // 4.2.1 var ymCollection = new YearMonth[] { new YearMonth(1980, 1), new YearMonth(1990, 4), new YearMonth(2000, 7), new YearMonth(2010, 9), new YearMonth(2020, 12), }; // 4.2.2 Exercise2_2(ymCollection); Console.WriteLine("----"); // 4.2.4 Exercise2_4(ymCollection); Console.WriteLine("----"); // 4.2.5 Exercise2_5(ymCollection); } // 4.2.3 static YearMonth FindFirst21C(YearMonth[] yms) { foreach (var ym in yms) { if (ym.Is21Century) return ym; } return null; } private static void Exercise2_2(YearMonth[] ymCollection) { foreach (var ym in ymCollection) { Console.WriteLine(ym); } } private static void Exercise2_4(YearMonth[] ymCollection) { var yearmonth = FindFirst21C(ymCollection); if (yearmonth == null) Console.WriteLine("21세기 데이터는 없습니다."); else Console.WriteLine(yearmonth); // 또는 다음과 같이 쓸 수도 있다 Console.WriteLine("----"); var yearmonth2 = FindFirst21C(ymCollection); var s = yearmonth2 == null ? "21세기 데이터가 없습니다." : yearmonth2.ToString(); Console.WriteLine(s); } private static void Exercise2_5(YearMonth[] ymCollection) { var array = ymCollection.Select(ym => ym.AddOneMonth()) .ToArray(); foreach (var ym in array) { Console.WriteLine(ym); } } } }
728x90'Development > C#' 카테고리의 다른 글
[프렉티컬 C#] 배열과 List<T> (0) 2023.07.26 [프렉티컬 C#] 문자열 처리 (0) 2023.07.26 [프랙티컬 C# 연습문제] 1부 - 3장 (0) 2023.07.15 [프랙티컬 C# 연습문제] 1부 - 2장 (0) 2023.07.14 [C#] 정적 메서드(static method)와 인스턴스 메서드(instance method) (0) 2023.07.14