https://msdn.microsoft.com/ko-kr/library/6a71f45d.aspx
+ 연산자
class Plus { static void Main() { Console.WriteLine(+5); // 단항 플러스(unary plus) Console.WriteLine(5 + 5); // 더하기(addition) Console.WriteLine(5 + .5); // 더하기(addition) Console.WriteLine("5" + "5"); // 문자열 연결(string concatenation) Console.WriteLine(5.0 + "5"); // 문자열 연결(string concatenation) // double 에서 문자열로 자동 변환된다. } } /* Output: 5 10 5.5 55 55 */
- 연산자
class MinusLinus { static void Main() { int a = 5; Console.WriteLine(-a); Console.WriteLine(a - 1); Console.WriteLine(a - .5); } } /* Output: -5 4 4.5 */
! 연산자
- 논리 부정 연산자 (!)는 피연산자를 부정하는 단항 연산자입니다.
- bool 형식으로 정의 되어 있고 false 인 경우에만 true를 반환합니다.
class MainClass4 { static void Main() { Console.WriteLine(!true); Console.WriteLine(!false); } } /* Output: False True */
~ 연산자
- 비트 보수 연산(bitwise complement operation)을 수행하여 각 비트를 반전시킵니다.
- 비트 보수 연산자는 int, uint, long, ulong 형에 대해 미리 정의 되어 있습니다.
참고
~ 기호는 소멸자를 선언하는 데에도 사용됩니다.
class BWC { static void Main() { int[] values = { 0, 0x111, 0xfffff, 0x8888, 0x22000022 }; foreach (int v in values) { Console.WriteLine("~0x{0:x8} = 0x{1:x8}", v, ~v); } } } /* Output: ~0x00000000 = 0xffffffff ~0x00000111 = 0xfffffeee ~0x000fffff = 0xfff00000 ~0x00008888 = 0xffff7777 ~0x22000022 = 0xddffffdd */
++ 연산자
- 증가 연산자(increment operator)는 피연산자를 1씩 증가시킵니다.
- 첫째 형태는 전위 증가 연산(prefix increment operation)입니다.
- 둘째 형태는 후위 증가 연산(postfix increment operation)입니다.
class MainClass { static void Main() { double x; x = 1.5; Console.WriteLine(++x); x = 1.5; Console.WriteLine(x++); Console.WriteLine(x); } } /* Output 2.5 1.5 2.5 */
-- 연산자
- 감소 연산자(decrement operator)는 피연산자를 1씩 감소시킵니다.
- 첫째 형태는 전위 감소 연산(prefix decrement operation)입니다.
- 둘째 형태는 후위 감소 연산(postfix decrement operation)입니다.
class MainClass5 { static void Main() { double x; x = 1.5; Console.WriteLine(--x); x = 1.5; Console.WriteLine(x--); Console.WriteLine(x); } } /* Output: 0.5 1.5 0.5 */
() 연산자
- 형식 캐스팅 (type casting)
- 연산의 순서를 지정하기 위해 사용합니다.
1. 캐스팅 또는 형식 변환을 지정합니다.
double x = 1234.7; int a; a = (int)x; // double 을 int 로 변환
2. 메서드 또는 대리자 호출(Invoke methods or delegates)
TestMethod();
3. 캐스트는 명시적으로(explicitly) 한 형식에서 다른 형식의 변환 연산자를 호출합니다.
4. 해당하는 변환 연산자가 정의되어 있지 않다면 캐스트는 실패합니다.
5. 변환 연산자 정의에 대해서는 explicit 및 implicit를 참조하십시오.
6. () 연산자는 오버로드되지 않습니다.
7. 캐스트 식을 사용하면 구문이 모호해질 수 있습니다.
8. 예를 들면 (x)-y 식을 -y 를 x 형식으로 변환한다고 해석할 수 있고,
9. 또는 x - y 의 가감식으로 해석될 수 있습니다.
Await
- 비동기 메서드(asynchronous method)의 작업에 적용됩니다.
- 대기 중인 작업이 완료 될때까지 메서드의 실행을 중단(suspend)시킵니다.
- 작업은 진행 중(ongoing)인 작업을 나타냅니다.
- await가 사용되는 비동기 메서드는 async 키워드로 수정해야 합니다.
- async 한정자를 사용해서 정의되고 일반적으로 하나 이상의 await 식을 포함하는 그러한 메소드는 비동기 메서드라고 합니다.
1. 일반적으로 await 연산자가 적용되는 작업은 작업 기반 비동기 패턴을 구현하는 메서드를 호출하여 얻은 반환값입니다.
2. 예는 Task 또는 Task<TResult> 형식의 값이 포함됩니다.
3. 다음 코드에서 HttpClient 메서드 GetByteArrayAsync는 Task<byte[]>, getContentsTask를 반환합니다.
4. 작업은 작업이 완료될 때 실제 바이트 배열을 생성하기 위한 약속입니다.
5. await 연산자는 getContentsTask에 적용되어 getContentsTask가 완료될 때까지 SumPageSizeAsync의 실행을 일시 중단합니다.
6. 동시에(In the meantime) 컨트롤은 SumPageSizesAsync 호출자에게 반환됩니다.
7. getContentsTask가 완료되면 await 식이 바이트 배열로 계산됩니다.
private async Task SumPageSizesAsync() { // 데스크탑 앱에서 HttpClient 형을 사용하려면 using 문을 사용해서 System.Net.Http 네임스페이스 참조를 추가해야 합니다. HttpClient client = new HttpClient(); // . . . Task<byte[]> getContentsTask = client.GetByteArrayAsync(url); byte[] urlContents = await getContentsTask; // 똑같이 한 줄의 코드로 작성할 수 있습니다. //byte[] urlContents = await client.GetByteArrayAsync(url); // . . . }
// Task<TResult>를 반환하는 메서드와 사용된 키워드 await TResult result = await AsyncMethodThatReturnsTaskTResult(); // Task를 반환하는 메서드와 사용된 키워드 await await AsyncMethodThatReturnsTask();
18. 대부분의 비동기 메서드는 Task 또는 Task<TResult>를 반환합니다.
19. 반환된 작업의 속성은 작업의 완료 여부, 비동기 메서드가 예외를 발생시켰거나, 취소되었는지의 여부, 최종 결과 등 해당 상태와 기록을에 대한 정보를 전달합니다.
20. await 연산자는 해당 속성에 액세스합니다.
21. 예외를 발생시키는 작업 반환 비동기 메서드를 기다릴 경우 await 연산자는 예외를 다시 던집니다.
22. 취소된 작업 반환 비동기 메서드를 기다릴 경우 await 연산자는 OperationCanceledException을 다시 throw합니다.
23. 오류가 발생한 상태의 단일 작업에는 여러 예외가 반영될 수 있습니다.
24. 예를 들어 작업은 Task.WhenAll 호출의 결과일 수 있습니다.
25. 이러한 작업을 기다릴 경우 await 작업에서 예외중 하나만 다시 던집니다.
26. 그러나 어떤 예외가 다시 던져질 지는 예측할 수 없습니다.
27. 비동기 메서드의 오류 처리에 대한 예제는 see try-catch를 잠조하세요.
예제
28. 다음 윈도우 폼 예제는 비동기 메서드 WaitAsynchronouslyasync에서의 await 사용을 보여줍니다.
29. 해당 메서드의 동작을 WaitAsynchronously의 동작과 대조(contrast)합니다.
30. await 연산자가 작업에 적용되지 않으면 본문에서 Thread.Sleep을 호출하더라도 WaitSynchronously 는 동기적(Synchronously)으로 실행됩니다.
private async void button1_Click(object sender, EventArgs e) { // 비동기적으로 실행하는 메서드 호출 string result = await WaitAsynchronouslyAsync(); // 다음은 동기적으로 실행하는 메서드 호출 //string result = await WaitSynchronously (); // 결과 표시 textBox1.Text += result; } // 다음 메서드는 비동기적으로 실행된다. // UI 스레드는 delay 동안에 차단되지 않는다. // Task.Delay가 실행되는 동안에 Form1 창을 이동하거나 리사이즈 할 수 있다. public async Task<string> WaitAsynchronouslyAsync() { await Task.Delay(10000); return "Finished"; } // 다음 메서드는 async의 사용에도 불구하고 동기적으로 실행된다. // Thread.Sleep이 실행되는 동안에 Form1 창을 이동하거나 리사이즈할 수 없다. // 왜냐하면 UI thread가 차단되었기 때문이다. public async Task<string> WaitSynchronously() { // System.Threading 에 대해서 using 문을 추가하라. Thread.Sleep(10000); return "Finished"; }
& 연산자
- & 연산자는 단항(unary) 또는 이항(binary) 연산자로 사용할 수 있습니다.
1. 단항 & 연산자는 피연산자(operand)의 주소를 반환합니다.(unsafe 컨텍스트 필요)
2. 이항 & 연산자는 정수 계열 형식(integral types)과 bool에 대해 미리 정의되어 있습니다.
3. 정수 계열 형식의 경우 & 연산자는 피연산자의 비트 논리 AND를 계산합니다.
4. bool 피연산자의 경우 & 연산자는 논리 AND를 계산합니다.
5. 즉, 두 피연산자가 모두 true인 경우에만 결과가 true 입니다.
6. & 연산자는 첫째 피연산자의 값에 상관없이 두 연산자를 모두 계산합니다.
int i = 0; if (false & ++i == 1) { // i는 증가되지만 조건 식은 false로 평가되어서 이 블록은 실행되지 않습니다. }
7. 사용자 정의 형식으로 이항 & 연산자를 오버로드할 수 있습니다.(operator 참조)
8. 정수 계열 형식에 대한 연산은 일반적으로 열거형(enumeration)에서 허용됩니다.
9. 이항 연산자가 오버로드되면 해당 대입 연산자(corresponding assignment operator)도 암시적으로 오버로드됩니다.
class BitwiseAnd { static void Main() { // 다음 두 문은 논리 AND를 수행합니다.. Console.WriteLine(true & false); Console.WriteLine(true & true); // 다음 라인은 F8 (1111 1000) 과 3F (0011 1111) 를 비트 AND 수행합니다. // 1111 1000 // 0011 1111 // --------- // 0011 1000 or 38 Console.WriteLine("0x{0:x}", 0xf8 & 0x3f); } } // Output: // False // True // 0x38
* 연산자
- 곱하기(multiplication) 연산자 (*)는 피연산자의 곱(product)을 계산합니다.
- 또한 포인터를 읽고 쓸 수 있는 역참조(dereference) 연산자 역할을 합니다.
1. 모든 숫자 형식에는 * 연산자가 미리 정의되어 있습니다.
2. * 연산자는 포인터 형식의 선언과 역참조에도 사용됩니다.
3. * 연산자는 unsafe 컨텍스트에서만 사용될 수 있고, /unsafe 컴파일러 옵션이 필요합니다.
4. 역참조 연산자는 또한 간접 참조(indirection) 연산자라고도 합니다.
5. 사용자 정의 형식으로 이항 * 연산자를 오버로드할 수 있습니다.
6. 이항 연산자가 오버로드되면 해당 대입 연산자도 암시적으로 오버로드 됩니다.
class Multiply { static void Main() { Console.WriteLine(5 * 2); Console.WriteLine(-.5 * .2); Console.WriteLine(-.5m * .2m); // decimal type } } /* Output 10 -0.1 -0.10 */
public class Pointer { unsafe static void Main() { int i = 5; int* j = &i; System.Console.WriteLine(*j); } } /* Output: 5 */
/ 연산자
- 나누기 연산자(division operator) (/)는 첫째 피 연산자에서 둘째 피연산자를 나눕니다.
- 모든 숫자 형식(All numeric types)에는 / 연산자가 미리 정의되어 있습니다.
1. 사용자 정의 형식으로 첫째 피연산자에서 둘째 피연산자를 나눕니다.
2. / 연산자를 오버로드하면 /= 연산자도 암시적으로 오버로드됩니다.
3. 두 정수(two integers)에 대해 나누기를 수행하면 결과는 항상 정수입니다.
4. 예를 들어 7 / 3 의 결과는 2입니다.
5. 7 / 3 의 나머지(remainder)를 확인(determine)하려면 나머지 연산자 (%) 를 사용합니다.
6. 몫(quotient)을 유리수(rational number)나 분수(fraction)로 가져오려면 피제수(dividend) 형식이나 divisor(제수) 형식을 float 이나 double로 지정합니다.
7. 다음 에제와 같이 숫자를 소수점의 오른쪽에 놓아서 피제수 또는 제수를 소수점 형태로 표현한다면 암시적으로 형식을 지정할 수 있습니다.
class Division { static void Main() { Console.WriteLine("\nDividing 7 by 3."); // 정수 몫은 2, 나머지는 1. Console.WriteLine("Integer quotient: {0}", 7 / 3); Console.WriteLine("Negative integer quotient: {0}", -7 / 3); Console.WriteLine("Remainder: {0}", 7 % 3); // Force a floating point quotient. float dividend = 7; Console.WriteLine("Floating point quotient: {0}", dividend / 3); Console.WriteLine("\nDividing 8 by 5."); // 정수 몫은 1, 나머지는 3. Console.WriteLine("Integer quotient: {0}", 8 / 5); Console.WriteLine("Negative integer quotient: {0}", 8 / -5); Console.WriteLine("Remainder: {0}", 8 % 5); // 부동소수점으로 암시적 표현 Console.WriteLine("Floating point quotient: {0}", 8 / 5.0); } } // Output: //Dividing 7 by 3. //Integer quotient: 2 //Negative integer quotient: -2 //Remainder: 1 //Floating point quotient: 2.33333333333333 //Dividing 8 by 5. //Integer quotient: 1 //Negative integer quotient: -1 //Remainder: 3 //Floating point quotient: 1.6
% 연산자
- % 연산자는 첫째 피연산자를 둘째 피연산자로 나눈 나머지를 계산합니다.
- 모든 숫자 형식은 나머지 연산자가 미리 정의되어 있습니다.
1. 사용자 정의 형식으로 % 연산자를 오버로드 할 수 있습니다.
2. 이항 연산자가 오버로드되면 해당 대입 연산자도 암시적으로 오버로드됩니다.
class MainClass6 { static void Main() { Console.WriteLine(5 % 2); // int Console.WriteLine(-5 % 2); // int Console.WriteLine(5.0 % 2.2); // double Console.WriteLine(5.0m % 2.2m); // decimal Console.WriteLine(-5.2 % 2.0); // double } } /* Output: 1 -1 0.6 0.6 -1.2 */
+ 연산자
- + 연산자는 단항 연산자로 사용하거나 이항 연산자로 사용할 수 있습니다.
1. 단항 + 연산자는 모든 숫자 형식에 대해 미리 정의되어 있습니다.
2. 숫자 형식에 대한 단항 + 연산자의 결과는 단순히 피연산자의 값입니다.
3. 이항 + 연산자는 숫자 형식과 문자열 형식에 대해 미리 정의되어 있습니다.
4. 숫자 형식의 경우, + 연산자는 두 피연산자의 합을 계산합니다.
5. 하나 또는 두 피연산자가 문자열 형식인 경우 + 연산자는 피연산자를 나타내는 문자열을 연결합니다.
6. 또한 대리자 형식도 이항 + 연산자를 제공합니다. 이 경우 대리자 연결을 수행합니다.
7. 사용자 정의 형식으로 단항 + 연산자와 이항 + 연산자를 오버로드할 수 있습니다.
8. 정수 계열 형식에 대한 연산은 일반적으로 열거형에서 허용됩니다.
class Plus { static void Main() { Console.WriteLine(+5); // unary plus Console.WriteLine(5 + 5); // addition Console.WriteLine(5 + .5); // addition Console.WriteLine("5" + "5"); // string concatenation Console.WriteLine(5.0 + "5"); // string concatenation // double 형에서 string 형으로 자동 변환된다. } } /* Output: 5 10 5.5 55 55 */
- 연산자
- - 연산자는 단항 연산자로 사용하거나 이항 연산자로 사용할 수 있습니다.
1. 단항 - 연산자는 모든 숫자 형식에 대해 미리 정의되어 있습니다.
2. 숫자 형식에 대한 단항 - 연산의 결과는 피연산자의 숫자 부정(negation)입니다.
3. 이항 - 연산자는 모든 숫자 형식과 열거 형식에 대해 첫째 피연산자에서 두번재 피연산자를 빼도록 미리 정의되어 있습니다.
4. 또한 대리자 형식도 이항 - 연산자를 제공합니다. 이 경우에는 대리자 제거를 수행합니다.
5. 사용자 정의 형식으로 단항 - 연산자와 이항 - 연산자를 오버로드할 수 있습니다.
class MinusLinus { static void Main() { int a = 5; Console.WriteLine(-a); Console.WriteLine(a - 1); Console.WriteLine(a - .5); } } /* Output: -5 4 4.5 */
<< 연산자
- 왼쪽 시프트 연산자(left-shift operator)는 첫째 피연산자를 둘째 피연산자에서 지정한 비트 수만큼 비트 다누이로 왼쪽으로 이동합니다.
- 두번째 피연산자 형식은 int 또는 int에 대한 미리 정의된 암시적 숫자 변환이 있는 형식이어야 합니다.
1. 첫째 피연산자가 int 또는 uint 형식이면 시프트 횟수는 둘째 피연산자의 하위 5비트로 지정됩니다. 즉, 실제 시프트 횟수는 0-31 비트입니다.
2. 첫째 피연산자가 64비트 용량의 long 또는 ulong 형식이면 시프트 횟수는 둘째 피연산자의 하위 6비트로 지정됩니다. 즉, 실제 시프트 횟수는 0-63 비트입니다.
3. 시프트 후 첫번째 피연산자의 형식 범위 내에 없는 상위 비트는 무시되고 하위의 빈 비트는 0으로 채워집니다.
4. 시프트 후 첫번째 피연산자의 형식 범위 내에 없는 상위 비트는 무시되고 하위의 빈 비트는 0으로 채워집니다. 시프트 연산은 오버플로를 일으키지 않습니다.
5. 사용자 정의 형식으로 << 연산자를 오버로드할 수 있습니다. 이 경우 첫째 피연산자의 형식은 사용자 정의 형식이어야 하며 둘째 피연산자의 형식은 int여야 합니다.
6. 이항 연산자가 오버로드되면 해당 대입 연산자도 암시적으로 오버로드됩니다.
class MainClass11 { static void Main() { int i = 1; long lg = 1; // i를 1비트 왼쪽으로 시프트합니다. 결과는 2입니다. Console.WriteLine("0x{0:x}", i << 1); // 2진수로, 33은 100001 입니다. // 하위 5비트의 값은 1이기 때문에 시프트의 결과는 2입니다. Console.WriteLine("0x{0:x}", i << 33); // lg의 형식은 long입니다. long 형식이기때문에 시프트는 하위 6비트의 값입니다. // 하위 6비트의 값은 100001 (33) 이기 때문에 왼쪽으로 33 시프트 됩니다. // In binary: 10 0000 0000 0000 0000 0000 0000 0000 0000 // In hexadecimal: 2 0 0 0 0 0 0 0 0 Console.WriteLine("0x{0:x}", lg << 33); } } /* Output: 0x2 0x2 0x200000000 */
'프로그래밍 > C#' 카테고리의 다른 글
C# 키워드 O~S (0) | 2016.05.31 |
---|---|
C# 키워드 F~N (0) | 2016.05.21 |
C# 키워드 A-E (0) | 2016.05.13 |
C# 총정리 (0) | 2016.04.19 |
정리 (0) | 2016.04.09 |