in..
메서드의 매개변수에 in변경자 추가 -> in은 ref + readonly이다..
값 복사 부하를 줄이기 위해서 ref로 변경한다면 오동할 수 있는 프로그램이 만들어 질 수 있다 -> 값 호출자쪽에서는 값변경을 원하지 않을 수도 있기때문이다 이를 위해서 ref + readonly인 in을 추가..
Vector v1 = new();
StructParam(in v1); // 불필요한 값 복사 없다.
void StructParam(in Vector v)
{
// v.x = 5; in으로 인해서 변경 불가
}
struct Vector
{
public int x { get; set; }
public int y { get; set; }
}
readonly 구조체
- 일반적으로 readonly는 값을 직접 변경하는 코드는 컴파일단계에서 오류가 발생한다. 하지만 메서드 호출에 대해서는 허용한다는 문제가..
이상한 행위..
readonly Vector v1 = new();
v1.Increment();
struct Vector
{
public int x { get; set; }
public int y { get; set; }
public void Increment()
{
x++;
y++;
}
}
위의 행위가 일어나는 것은 c#의 방어 복사본처리때문이다. c# 컴파일러는 readonly가 적용된 구조체 인스턴스에 한해 그 상태를 유지할 수 있도록한다...
컴파일러가 처리하는 행위는 -> Vector tmp = v1; //원본 v1을 변경하지 않도록 방어 복사본 처리.. , tmp.Increment();
올바른 행위..
readonly Vector v1 = new();
readonly struct Vector
{
readonly public int x;
readonly public int y;
}
- readonly struct 값에 대해서는 내부 맴버에 대해서도 모두 readonly를 붙일 것을 강제한다 그래서 위의 이상한 행위 예제는 될 수 없다..
ref struct
- struct는 스택을 사용하지만 struct가 class안에 정의된 경우에는 힙에 데이터가 위치하게된다... 값 형식을 스택에만 생성할 수 있도록 강제할 수 있는 방법이 ref struct이다...
ref struct Matrix // : IDisposable Interface를 구현할 수 없다..-> 왜냐하면 인스턴스로 형변환은 스택 객체가 힙객체로 반환돼야 하는 박싱 작업
{
public Vector v1; //ref struct vector...
public Vector v2;
}
- 한가지 제약은 interface를 구현할 수없다.. 하지만 8.0인가 추후에 보면 ref struct안에서도 void Dispose를 구현한다면 using을 사용할 수 있도록해주었다..
제네릭 제약조건이 system.Delegate, system.Enum에 대해서는 풀린다...
{
Action action = () => { Console.WriteLine("Action"); };
ActionProxy<Action> proxy = new(action);
proxy.Call();
}
{
Action<string> action = (arg) => { Console.WriteLine($"{arg}"); };
ActionProxy<Action<string>> proxy = new(action);
proxy.Call();
}
class ActionProxy<T> where T : System.Delegate
{
private T _callbackFunc;
public ActionProxy(T callbackFunc)
{
_callbackFunc = callbackFunc;
}
public void Call()
{
switch (_callbackFunc)
{
case Action action:
action();
break;
case Action<string> action:
action("kcjkcjkcjckjckcjkcom2");
break;
}
}
}
^ .. 연산자..
string text = "kcj3054";
System.Range full = 0..^0;
string copy = text[full];
범위연산자.. ^n연산자는 뒤에서부터 시작된다 , 참고로 인덱스 연산자는 마지막 위치를 1로한다..
n1..n2 [) 범위랑 동일하다..
간결해진 using
- 기존
using (var file = new System.IO.StreamReader("TSDFA.TXT"))
{
//~~
}
- 변하된 것
void Init()
{
using var file2 = new StreamReader("TEST.TXT");
string txt = file2.ReadToEnd();
//~~
}
- 기존의 using문을 보면 { 중괄호로 범위를 나타내주고 있다 해당 범위 안이면 Idspose같은 자동적으로 dispose해준다. 그렇지만 더 편리해진 using은.. 범위가 가장 가까운 중괄호로변하게 된다.. 편리하다.
부분 메서드..
- 부분 메서드는 코드는 분할하지 않고.. 단지 메서드의 선언과 구현부를 분리할 수 있게 허용한다..
MyTest myTest = new();
myTest.WriteTest();
partial class MyTest
{
partial void Log(object obj);
public void WriteTest()
{
this.Log("call test!");
}
}
//다른 파일
partial class MyTest
{
partial void Log(Object obj)
{
Console.WriteLine(obj.ToString());
}
}
- 위에서 보듯이 Log메서드는 위쪽에는 선언부분만 있지만, 아랫부분에는 구현부까지 존재한다
컬렉션과 람다메서드
List<int> list = new List<int>() {1, 2, 3, 4, 5};
list.ForEach((elemn) => {Console.WriteLine(elemn);} );
Array.ForEach(list.ToArray(),
(elem) => {Console.WriteLine(elem);});
list.ForEach(delegate(int elem) {Console.WriteLine(elem);});
- 위에서 보듯이 컬렉션 list에서 ForEach를 이용해서 list의 값들을 순회할 수도있고, 람다식이 아닌 익명 메서드로도 가능하고... , ForEach 메서드는 Action
를 델리게이트 인자로 받는다..
lock 처리
void ThreadFunc(object obj)
{
MyData data = new();
for (int i = 0; i < 100; i++)
{
lock (data)
{
data.Increment();
}
}
}
public class MyData
{
private int number = 0;
public object _numberLock = new();
public int Number { get { return number; } }
public void Increment()
{
lock (_numberLock)
{
number++;
}
}
}
- 예시이다.. lock을해도되고 try catch.. finally.. + enter 조합으로도 가능하다..
stringBuilder...
- string을 사용할 때 + 연산이 많은 경우 바로 사용하지 않고 stringBuilder를 사용하는 부분이 많다는 것을 볼 수 있다 해당 이유는 + 연산을 할 때마다 heap 메모리를 잡아 먹을 수 있기때문이다. 그렇게 때문에 builder안에 존재하는 append를 이용하면 heap영역에 메모리를 잡아 먹지 않을 수 있다.
using System.Text;
string txt = "kcj3054";
StringBuilder sb= new();
sb.Append(txt);
for (int i = 0; i < 1000; ++i)
{
sb.Append('1');
}
- 위의 표현에서 append로 붙이지않고 1000번의 모든 연산을 +로 한다면 어마어마하게 손실이 발생한다..
종료자..
span
..
- 출처 : 시작하세요 C# 9.0 프로그래밍..
'c#' 카테고리의 다른 글
semaphore.. (1) | 2022.12.06 |
---|---|
c# 패턴매칭... switch case에 활용.. (0) | 2022.12.06 |
Generic, where, using static (0) | 2022.12.06 |
Task vs TaskValue (0) | 2022.12.06 |
c# (시작하세요 c# 프로그래밍 도서 ) (0) | 2022.12.05 |