일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- c# winform
- c언어
- 깃
- git
- jupyter
- C++
- HTML
- Python
- jupyter lab
- 유니티
- c# 추상 클래스
- dart 언어
- Flutter
- 도커
- Data Structure
- gitlab
- 플러터
- Algorithm
- github
- docker
- vim
- Houdini
- c# 윈폼
- C# delegate
- C언어 포인터
- 다트 언어
- Unity
- 구조체
- c#
- 포인터
- Today
- Total
목록c# (56)
nomad-programmer
일반화 메소드나 일반화 클래스가 입력받는 형식 매개 변수 T는 "모든" 데이터 형식을 대신할 수 있다. 이렇게 모든 형식에 대응할 수 있는 형식 매개 변수가 필요한 때도 있지만, 종종 특정 조건을 갖춘 형식에만 대응하는 형식 매개 변수가 필요할 때도 있다. 이 때 형식 매개 변수의 조건에 제약을 줄 수 있다. 예를 들어 MyList 클래스의 형식 매개 변수 T에 "MyClass 로부터 상속받는 형식이어야 할 것" 이라는 제약을 주면 다음과 같이 클래스 선언문의 헤더에 where 절을 추가해주면 된다. class MyList where T : MyClass { // ... } 일반화 메소드도 비슷하다. CopyArray() 의 형식 매개 변수 T에 "값 형식이어야 할 것" 이라는 제약은 다음과 같이 줄 수..
인덱서(Indexer) 는 인덱스(Index) 를 이용해서 객체 내의 데이터에 접근하게 해주는 프로퍼티라고 생각하면 된다. 객체를 마치 배열처럼 사용할 수 있게 해준다. 인덱서를 선언하는 형식은 다음과 같다. class 클래스이름 { // 인덱스의 식별자가 꼭 index라는 이름일 필요는 없다. 한정자 인덱서형식 this[형식 index] { get { // index를 이용하여 내부 데이터 반환 } set { // index를 이용하여 내부 데이터 저장 } } } 인덱서는 프로퍼티처럼 식별자(변수 이름) 를 따로 가지지 않는다. 프로퍼티가 이름을 통해 객체 내의 데이터에 접근하게 해준다면, 인덱서는 인덱스를 통해 객체 내의 데이터에 접근하게 해준다. using System; using System.Co..
컬렉션이란, 같은 성격을 띄는 데이터의 모음을 담는 자료 구조를 말한다. 배열도 .NET Framework가 제공하는 다양한 컬렉션 자료 구조의 일부이다. .NET Framework의 여타 컬렉션들이 상속하게 되어 있는 ICollection 인터페이스를 상속함으로써 System.Array 클래스 자신이 컬렉션의 일원임을 증명하고 있다. public abstract class Array : ICloneable, IList, ICollection, IEnumerable .NET Framework는 배열 말고도 여러 컬렉션 클래스들을 제공한다. ArrayList (자료 구조에서의 Linked List, Python에서는 list) Queue (Python에서 Queue 모듈) Stack (Python에서 li..
2차원 배열이나 3차원 배열 같은 다차원 배열을 "배열을 요소로 갖는 배열" 이다. 허나 진정한 의미에서의 배열을 요소로 갖는 배열은 "가변 배열 (Jagged Array)" 이다. 가변 배열은 다양한 길이의 배열을 요소로 가지는 다차원 배열로 이용될 수 있다. 2차원 배열의 요소에 접근할 때 반드시 첨자 두 개를 사용해야 했다. 하나만 사용해서 1차원 배열에 접근한다거나 하는 일은 불가능하다. 아래의 예를 보자. int[,] arr2d = new int[2, 3] { {1, 2, 3}, {4, 5, 6} }; // 2차원 배열이면 첨자 2개가 필히 들어가야 한다. arr2d[1, 2]; // 2차원 배열이면 첨자가 1개 뿐이라면 에러 발생. 1차원 배열에 접근할 수 없다... arr2d[1]; 가변 배..
다차원 배열이란 차원이 둘 이상인 배열을 말한다. 2차원 배열도 다차원 배열에 해당한다. using System; namespace test { internal class Program { public static void Main(string[] args) { int[,,] arr3d = new int[4, 3, 2] { { {0, 1}, {2, 3}, {4, 5} }, { {6, 7}, {8, 9}, {10, 11} }, { {12, 13}, {14, 15}, {16, 17} }, { {18, 19}, {20, 21}, {22, 23} } }; for (int i = 0; i < arr3d.GetLength(0); i++) { for (int j = 0; j < arr3d.GetLength(1); j..
C#에서는 모든 것이 객체이다. 배열도 객체이며 당연히 기반이 되는 형식이 있다. .NET Framework의 CTS (Common Type System) 에서 배열은 System.Array 클래스에 대응된다. 따라서 System.Array의 특성과 메소드를 파악하면 배열의 특성과 메소드를 알게 되는 셈이다. Array 클래스의 주요 메소드와 프로퍼티 분류 이름 설명 정적 메소드 Sort() 배열을 정렬한다. BinarySearch() 이진 탐색을 수행한다. IndexOf() 배열에서 찾고자 하는 특정 데이터의 인덱스를 반환한다. TrueForAll() 배열의 모드 요소가 지정한 조건에 부합하는지의 여부를 반환한다. FindIndex() 배열에서 지정한 조건에 부합하는 첫 번째 요소의 인덱스를 반환한다...
추상 클래스는 클래스처럼 구현된 프로퍼티를 가질 수도 있는 한편, 인터페이스처럼 구현되지 않은 프로퍼티도 가질 수 있다. 추상 클래스에서는 이것을 "추상 프로퍼티 (Abstract Property)" 라고 한다. 추상 메소드가 그랬던 것처럼, 추상 프로퍼티 역시 인터페이스의 프로퍼티와 다를 것이 없다. 파생 클래스가 해당 프로퍼티를 구현하도록 강제하는 것일 뿐이다. 추상 프로퍼티는 인터페이스처럼 구현을 비워놓은 것만으로는 추상 프로퍼티를 만들 수 없다. 그리하면 C# 컴파일러가 자동 구현 프로퍼티로 간주하고 구현을 자동으로 채워 넣을 것이다. 그래서 추상 프로퍼티는 abstract 한정자를 이용하여 선언한다. abstract class 추상 클래스이름 { abstract 데이터형식 프로퍼티이름 { get..
인터페이스는 메소드뿐만 아니라 프로퍼티와 인덱서도 가질 수 있다. 프로퍼티나 인덱서를 가진 인터페이스를 상속하는 클래스가 반드시 해당 프로퍼티와 인덱서를 구현해야 하는 것은 물론이다. 당연한 이야기지만 인터페이스에 들어가는 프로퍼티는 구현을 갖지 않는다. 인터페이스의 프로퍼티 선언이 클라스의 자동 구현 프ㅗ퍼티 선언과 그 모습이 동일하다. 다음은 인터페이스의 프로퍼티 선언 형식이다. interface 인터페이스이름 { public 형식 프로퍼티1 { get; set; } public 형식 프로퍼티2 { get; set; } } 다음은 프로퍼티를 갖고 있는 인터페이스와 이를 상속하는 파생 클래스의 예이다. interface INameInfo { string Name { get; set; } } class ..
이름이 없는 형식, 즉 "무명 형식 (Anonymous Type)" 의 프로퍼티를 정의할 수 있다. 무명 형식은 형식의 선언과 동시에 인스턴스를 할당한다. 이 때문에 인스턴스를 만들고 다시는 사용하지 않을 때 요기하게 쓰인다. // 괄호 사이에 임의의 프로퍼티 이름을 적고 값을 할당하면 그대로 새 형식의 프로퍼티가 된다. var myInstance = new { Name = "test", Age = 17 }; Console.WriteLine( myInstance.Name, myInstance.Age ); 무명 형식에는 주의할 점이 있다. 그것은 무명 형식의 프로퍼티에 할당된 값은 변경 불가라는 점이다. 한마디로 한번 무명 형식의 인스턴스가 만들어지고 난 다음에는 읽기만 할 수 있다는 것이다. 이러한 특징..
프로퍼티를 이용한 초기화는 다음과 같다. 클래스이름 인스턴스 = new 클래스이름() { 프로퍼티1 = 값, 프로퍼티2 = 값, 프로퍼티3 = 값 } 객체를 생성할 때 목록에 객체의 모든 프로퍼티가 올 필요는 없다. 초기화하고 싶은 프로퍼티만 넣어서 초기화하면 된다. 매개 변수가 있는 생성자를 작성할 때와는 달리 어떤 필드를 생성자 안에서 초기화할지를 미리 고민할 필요가 없다. using System; namespace CSharpExample { class MainApp { class BirthdayInfo { public string Name { get; set; } public DateTime Birthday { get; set; } public int Age { get { return new Da..
프로퍼티는 데이터의 오염에 대해선 메소드처럼 안전하고, 데이터를 다룰 때는 필드처럼 간결하다. 하지만 많은 경우 중복된 코드를 작성하고 있다는 기분이 들게 된다. 다음 코드의 NameCard 클래스를 보면 Name과 PhoneNumber 프로퍼티는 단순히 name과 phoneNumber 필드를 읽고 쓰기만 하고 있다. 여기에는 아무 논리도 섞여 있지 않다. 이런 경우 C# 언어는 더 단순하게 만드는 "자동 구현 프로퍼티 (Auto-Implemented Property)" 를 C# 3.0 때 도입했다. public class NameCard { private string name; private string phoneNumber; public string Name { get { return name; } ..
C#의 복합 데이터 형식에는 클래스 말고도 구조체(Structure)라는 것이 있다. 구조체는 클래스하고 사촌지간쯤 된다. 필드와 메소드를 가질 수 있는 등 상당 부분 비슷하다. struct 구조체이름 { // 필드, ... // 메소드, ... } struct MyStruct { public int field1 public int field2 public void MyMethod() { } } 구조체에서 public을 많이 사용하는 이유? 문법적으로 클래스와 유사하기는 해도, 각자의 존재의 이유는 조금 다르다. 클래스는 실세계의 객체를 추상화하려는데 그 존재의 이유가 있지만, 구조체는 데이터를 담기 위한 자료 구조로 사용된다. 따라서 굳이 은닉성을 비롯한 객체 지향의 원칙을 구조체에 강하게 적용하지는 ..
정수와 문자열 형식 외에도, C# 7.0부터 switch문에 데이터 형식을 조건으로 사용할 수 있게 되었다. 데이터 형식에 따라 분기할 때에는 case 절에서 데이터 형식 옆에 반드시 식별자를 붙여줘야 한다. 선언한 식별자는 case 절 안에서 사용할 수 있다. 또한 when 절을 이용하여 추가적인 조건 검사를 수행할 수 있다. when은 case 절에 붙여 사용한다. when 절을 if 문과 비슷하다고 생각하면 된다. using System; namespace CSharpExam { class SwitchExample { static int Main(string[] args) { object obj = null; string s = Console.ReadLine(); if (int.TryParse(s,..
공용 형식 시스템의 형식 클래스 이름 C# 형식 C++ 형식 VB 형식 System.Byte byte unsigned char Byte System.SByte sbyte char SByte System.Int16 short short Short System.Int32 int int 또는 long Integer System.Int64 long __int64 Long System.UInt16 ushort unsigned short UShort System.UInt32 uint unsigned int 또는 unsigned long UInteger System.Uint64 ulong unsigned __int64 ULong System.Single float float Single System.Double do..
C#은 변수나 상수에 대해 꼼꼼히 형식 검사를 진행하는 강력한 형식의 언어이다. 강력한 형식 검사는 프로그래머의 실수르 줄여 주는 장점이 있다. 의도치 않은 형식의 데이터를 읽거나 할당하는 일을 막아준다. 예를 들어 원래는 정수 형식의 데이터를 담기 위해 n이라는 변수를 선언했는데, 다른 프로그래머가 이 코드를 물려받아서는 중간에 문자열 형식을 담아 쓰려고 할 수 있다. 약한 형식 검사는 이런 문제를 막을 수 없지만, 강력한 형식 검사는 이 문제를 컴파일 타임에 찾아내 드러내 준다. 하지만 약한 형식 검사가 단점만 있는 것은 아니다. 코드를 작성하는 단계에서는 약한 형식 검사가 더 편리하다. 귀찮게 int, long, uint, ulong 등과 같은 형식을 외울 필요 없이 일단 변수를 선언해서 데이터를 ..
오버플로우 (Overflow) 변수는 데이터를 담는 그릇과 같다. 그릇에 용량을 넘어사는 양의 물을 담으면 넘치는 것처럼, 변수에도 데이터 형식의 크기를 넘어서는 값을 담으면 넘쳐 흐른다. 이런 현상을 "오버플로우(Overflow)"라고 한다. using System; namespace FlowExam { class FlowExample { static int Main(string[] args) { byte variable = byte.MaxValue; Console.WriteLine($"{variable}"); // 오버플로우 발생 variable++; Console.WriteLine($"{variable}"); return 0; } } } /* 결과 255 0 */ byte의 최대값은 255이다. 2..