C\#중 9 개의'흑 마법'
C#
매우 선진 적 인 언어 라 는 것 을 안다.왜냐하면 그것 은 멀리 볼 수 있 는'문법 사탕'이기 때문이다.이런'문법 사탕'들 은 때때로 너무 쓰기 좋아 서 어떤 사람들 은 그것 이C#
컴 파일 러 가 죽은 것 이 라 고 생각 하고 이치 에 맞지 않 는 다―약간'흑 마법'과 같다.그러면 우 리 는
C#
이런 고급 언어 기능 이 컴 파일 러 가 죽은 것('흑 마법')인지,아니면 확장 할 수 있 는'오리 유형'인지 볼 수 있다.제 가 먼저 디 렉 터 리 를 만 들 겠 습 니 다.여러분 은 이 디 렉 터 리 에 대해'흑 마법'(컴 파일 러 가 죽 었 다 고 쓰 여 있 는 지)인지'오리 유형'인지 판단 해 보 세 요.
LINQ
조작,그리고IEnumerable<T>
유형'흑 마술'이 아니 라'오리 스타일'입 니 다.
LINQ
는C# 3.0
발표 한 새로운 기능 으로 데 이 터 를 매우 편리 하 게 조작 할 수 있다.현재12
년 이 지 났 습 니 다.비록 일부 기능 이 강화 되 어야 하지만 다른 언어 에 비해 훨씬 편리 합 니 다.제 가 지난 블 로그 에서 언급 한 바 와 같이
LINQ
꼭IEnumerable<T>
을 바탕 으로 하 는 것 이 아니 라 하나의 유형 을 정 하고 필요 한LINQ
표현 식 을 실현 하면 됩 니 다.LINQ
의select
키 워드 는 호출.Select
방법 으로 다음 과 같은'소조 작'으로'꽃 을 옮 겨 나 무 를 연결 하 는'효 과 를 실현 할 수 있 습 니 다.
void Main()
{
var query =
from i in new F()
select 3;
Console.WriteLine(string.Join(",", query)); // 0,1,2,3,4
}
class F
{
public IEnumerable<int> Select<R>(Func<int, R> t)
{
for (var i = 0; i < 5; ++i)
{
yield return i;
}
}
}
2.async/await
와Task
/ValueTask
유형'흑 마술'이 아니 라'오리 스타일'입 니 다.
async/await
은C# 5.0
에 발표 되 었 고 비동기 프로 그래 밍 을 매우 편리 하 게 할 수 있 으 며 그 본질은 상태 기 이다.async/await
의 본질은 다음 유형의 이름GetAwaiter()
인 터 페 이 스 를 찾 는 것 이다.이 인 터 페 이 스 는INotifyCompletion
또는ICriticalNotifyCompletion
에 계승 되 는 종 류 를 되 돌려 야 하 며,이 종 류 는GetResult()
방법 과IsComplete
속성 을 실현 해 야 한다.만약 a 가 ICriticalNotifyComplete 를 실현 했다 면,실행(a as ICriticalNotifyComplete).OnComplete(action)
실행 후 일시 정지,OnComplete 완료 후 다시 상태 기 로 돌아 가기;
관심 있 는 방문 가능
Github
구체 적 인 규범 설명:https://github.com/dotnet/csharplang/blob/master/spec/expressions.md정상
Task.Delay()
은
을 바탕 으로 다음 과 같은'소 조작'으로 하나의 단일 스 레 드TaskEx.Delay()
를 실현 할 수 있다.
static Action Tick = null;
void Main()
{
Start();
while (true)
{
if (Tick != null) Tick();
Thread.Sleep(1);
}
}
async void Start()
{
Console.WriteLine(" ");
for (int i = 1; i <= 4; ++i)
{
Console.WriteLine($" {i} , :{DateTime.Now.ToString("HH:mm:ss")} - :{Thread.CurrentThread.ManagedThreadId}");
await TaskEx.Delay(1000);
}
Console.WriteLine(" ");
}
class TaskEx
{
public static MyDelay Delay(int ms) => new MyDelay(ms);
}
class MyDelay : INotifyCompletion
{
private readonly double _start;
private readonly int _ms;
public MyDelay(int ms)
{
_start = Util.ElapsedTime.TotalMilliseconds;
_ms = ms;
}
internal MyDelay GetAwaiter() => this;
public void OnCompleted(Action continuation)
{
Tick += Check;
void Check()
{
if (Util.ElapsedTime.TotalMilliseconds - _start > _ms)
{
continuation();
Tick -= Check;
}
}
}
public void GetResult() {}
public bool IsCompleted => false;
}
실행 효 과 는 다음 과 같 습 니 다:실행 시작
제 1 회,시간:17:38:03-스 레 드 번호:1
두 번 째,시간:17:38:04-스 레 드 번호:1
세 번 째,시간:17:38:05-스 레 드 번호:1
제 4 회,시간:17:38:06-스 레 드 번호:1
실행 완료
굳이 사용 하지 않 아 도
TaskCompletionSource<T>
정 의 된async/await
을 만 들 수 있 습 니 다.3.표현 식 트 리 와
Expression<T>
유형'흑 마법'입 니 다.'조작 공간'이 없습니다.형식 이
Expression<T>
일 때 만 표현 식 트 리 로 만 들 수 있 습 니 다.
는C# 3.0
함께 발표 되면 서 멀리 내다 보 는'흑 마술'이다.다음 코드 와 같이:
Expression<Func<int>> g3 = () => 3;
컴 파 일 러 에 의 해 다음 과 같이 번 역 됩 니 다.
Expression<Func<int>> g3 = Expression.Lambda<Func<int>>(
Expression.Constant(3, typeof(int)),
Array.Empty<ParameterExpression>());
4.플러그 인 문자열 과LINQ
형식'흑 마술'입 니 다.'조작 공간'이 없습니다.
FormattableString
은
에 발표 되 었 고 그 전에 많은 언어 들 이 비슷 한 기능 을 제공 했다.유형 이
C# 6.0
일 때 만 다음 코드 와 같은 다른 컴 파일 결 과 를 얻 을 수 있 습 니 다.
FormattableString x1 = $"Hello {42}";
string x2 = $"Hello {42}";
컴 파일 러 생 성 결 과 는 다음 과 같 습 니 다.
FormattableString x1 = FormattableStringFactory.Create("Hello {0}", 42);
string x2 = string.Format("Hello {0}", 42);
본질 적 으로FormattableString
를 호출 하여 유형 을 만 드 는 것 이 므 로 주의 하 십시오.5.
FormattableStringFactory.Create
와yield return
유형;흑 마술 이지 만 보충 설명 이 있다.
IEnumerable<T>
는yield return
이외에IEnumerable<T>
,IEnumerable
,IEnumerator<T>
,IEnumerator
에 도 사용 할 수 있다.따라서
C#
로C++
/Java
의generator<T>
행동 을 모 의 하려 면 간단 하 다.
var seq = GetNumbers();
seq.MoveNext();
Console.WriteLine(seq.Current); // 0
seq.MoveNext();
Console.WriteLine(seq.Current); // 1
seq.MoveNext();
Console.WriteLine(seq.Current); // 2
seq.MoveNext();
Console.WriteLine(seq.Current); // 3
seq.MoveNext();
Console.WriteLine(seq.Current); // 4
IEnumerator<int> GetNumbers()
{
for (var i = 0; i < 5; ++i)
yield return i;
}
yield return
―교체 기 는C# 2.0
에 발표 되 었 다.6.
foreach
순환,IEnumerable<T>
유형'오리 유형'으로'조작 공간'이 있 습 니 다.
foreach
굳이 사용IEnumerable<T>
유형 에 협조 하지 않 고 대상 이 존재 하 는GetEnumerator()
방법 만 있 으 면 된다.
void Main()
{
foreach (var i in new F())
{
Console.Write(i + ", "); // 1, 2, 3, 4, 5,
}
}
class F
{
public IEnumerator<int> GetEnumerator()
{
for (var i = 0; i < 5; ++i)
{
yield return i;
}
}
}
또한 대상 이GetAsyncEnumerator()
이 루어 지면await foreach
비동기 순환 도 똑 같이 사용 할 수 있다.
async Task Main()
{
await foreach (var i in new F())
{
Console.Write(i + ", "); // 1, 2, 3, 4, 5,
}
}
class F
{
public async IAsyncEnumerator<int> GetAsyncEnumerator()
{
for (var i = 0; i < 5; ++i)
{
await Task.Delay(1);
yield return i;
}
}
}
await foreach
는C# 8.0
과 함께 발 표 된 것 으로 내 가 전에 쓴'코드 프 리 젠 테 이 션 C\#버 전 별 새로운 기능'을 구체 적 으로 볼 수 있다.7.
키워드 와using
인터페이스네,아니에요.
IDisposable
과 정상 적 인
용
키 워드 는using
인 터 페 이 스 를 기반 으로 해 야 합 니 다.그러나
IDisposable
와ref struct
는 또 다른 이야기 다.그러나 자원 을 방출 하 는 수요 가 여전히 존재 한다.어 떡 하지?'오리 유형'이 오 면 손 으로
IAsyncDisposable
방법 을 쓸 수 있 고 그 어떠한 인터페이스 도 계승 할 필요 가 없다.
void S1Demo()
{
using S1 s1 = new S1();
}
ref struct S1
{
public void Dispose()
{
Console.WriteLine(" ");
}
}
같은 이치 로ref struct
인 터 페 이 스 를 사용 하면:
async Task S2Demo()
{
await using S2 s2 = new S2();
}
struct S2 : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
await Task.Delay(1);
Console.WriteLine("Async ");
}
}
8.ref struct
와
유형'흑 마법'으로
만 받 아들 일 수 있다
.
는 하나의Dispose()
로 서 직접 받 아들 일 수 있다IAsyncDisposable
값(정상T?
은 받 아들 일 수 없다Nullable<T>
값 이다.예제 코드 는 다음 과 같다.
int? t1 = null;
Nullable<int> t2 = null;
int t3 = null; // Error CS0037: Cannot convert null to 'int' because it is a non-nullable value type
생 성 코드 는 다음 과 같 습 니 다Nullable<T>
.T?
와 똑 같 습 니 다.컴 파일 에 실패 한 코드 를 건 너 뛰 었 습 니 다):
IL_0000: nop
IL_0001: ldloca.s 0
IL_0003: initobj valuetype [System.Runtime]System.Nullable`1<int32>
IL_0009: ldloca.s 1
IL_000b: initobj valuetype [System.Runtime]System.Nullable`1<int32>
IL_0011: ret
9.임의의 유형의Nullable<T>
범 형 조작'흑 마법'도 있 고'오리 유형'도 있다.조작 공간 이 존재 한다.
은null
에 발표 되 어
처럼 색인 위 치 를 편리 하 게 조작 하고 대응 치 를 꺼 낼 수 있다.예전 에는 호출null
등 복잡 한 조작 이 필 요 했 는데 지금 은 매우 간단 하 다.
string url = "https://www.super-cool.com/product/7705a33a-4d2c-455d-a42c-c95e6ac8ee99/summary";
string productId = url[35..url.LastIndexOf("/")];
Console.WriteLine(productId);
생 성 코드 는 다음 과 같 습 니 다:
string url = "https://www.super-cool.com/product/7705a33a-4d2c-455d-a42c-c95e6ac8ee99/amd-r7-3800x";
int num = 35;
int length = url.LastIndexOf("/") - num;
string productId = url.Substring(num, length);
Console.WriteLine(productId); // 7705a33a-4d2c-455d-a42c-c95e6ac8ee99
이 를 통 해 알 수 있 듯 이int?
컴 파일 러 는 무시Nullable<int>
하고 호출Index/Range
으로 직접 번역 했다.그러나 배열 은 다르다.
var range = new[] { 1, 2, 3, 4, 5 }[1..3];
Console.WriteLine(string.Join(", ", range)); // 2, 3
생 성 코드 는 다음 과 같 습 니 다:
int[] range = RuntimeHelpers.GetSubArray<int>(new int[5]
{
1,
2,
3,
4,
5
}, new Range(1, 3));
Console.WriteLine(string.Join<int>(", ", range));
이 를 통 해 알 수 있 듯 이Index/Range
유형 을 만 들 었 고C# 8.0
호출 되 었 으 며 완전히'흑 마법'에 속한다.그러나 이것 은'오리'유형 이기 도 하 다.코드 에서
Python
속성 과Substring
방법 을 실현 하면 호출 할 수 있다C#
.
var range2 = new F()[2..];
Console.WriteLine(range2); // 2 -> -2
class F
{
public int Length { get; set; }
public IEnumerable<int> Slice(int start, int end)
{
yield return start;
yield return end;
}
}
생 성 코드 는 다음 과 같 습 니 다:
F f = new F();
int length2 = f.Length;
length = 2;
num = length2 - length;
string range2 = f.Slice(length, num);
Console.WriteLine(range2);
총결산위 에서 보 듯 이
Index/Range
'검 은 마법'은 확실히 많 지만'오리 유형'도 많아'소 조작'의'조작 공간'이 크다.Substring
'오리 유형'의 원조 인Range
가 추 가 될 것 으로 알려 졌 다.그 때 는'조작 공간'이 지금 보다 더 클 것 이 라 고 기대 하고 있다.C\#중 9 개의'흑 마법'에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 c\#흑 마법 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.