>  기사  >  백엔드 개발  >  C# 제네릭 사용에 대한 간략한 토론

C# 제네릭 사용에 대한 간략한 토론

黄舟
黄舟원래의
2016-12-21 14:48:581218검색

C# 제네릭을 사용하는 이유는 무엇입니까?

이 문제를 이해하기 위해 먼저 다음 코드를 살펴보겠습니다. 코드에는 일부 내용이 생략되어 있지만 함수는 int만 처리할 수 있는 스택을 구현하는 것입니다. 데이터 유형:

public class Stack { This.m_item = new int[i] } } 위 코드는 매우 잘 실행되지만 문자열 유형을 저장하기 위해 스택이 필요한 경우 어떻게 해야 합니까? 많은 사람들은 위의 코드를 복사해서 int를 string으로 바꾸는 것을 생각할 것이다. 물론 이 작업 자체로는 문제가 없지만, 좋은 프로그램이라면 나중에 다시 long이나 Node 형태의 스택이 필요할 때 어떻게 해야 할지 고민하기 때문에 이렇게 하지 않을 것입니다. 다시 복사하시겠습니까? 뛰어난 프로그래머라면 이 스택을 구현하기 위해 공통 데이터 유형 객체를 사용하는 것을 고려할 것입니다. ){...} public Stack(int i) { this.m_item = new[i]; 이 스택은 매우 유연하며 작성이 가능합니다. 모든 데이터 유형을 수신하면 한번에 완료된다고 할 수 있습니다. 그러나 종합적으로 말하면 결함이 없는 것은 아닙니다.

Stack이 값 유형을 처리할 때 Boxing 및 Folding 작업이 발생하여 관리되는 힙에 많은 수의 변수가 할당되고 재활용됩니다. 데이터의 양이 많으면 성능 손실이 매우 심각합니다.

참조 유형을 처리할 때 박싱이나 접기 연산이 없더라도 데이터 유형 강제 연산을 사용하므로 프로세서의 부담이 늘어납니다.

데이터 유형 강제 변환에는 더 심각한 문제가 있습니다(스택이 스택의 인스턴스라고 가정).

Node1 x = new Node1(); Node2 y = (Node2)stack.Pop() ; 위 코드는 컴파일시에는 전혀 문제가 없으나 Node1 타입의 데이터가 push되기 때문에 Pop시 Node2 타입으로 변환을 해줘야 하는데 이때 타입변환 예외가 발생하게 됩니다. 컴파일러의 검사를 피했습니다.

객체 유형 스택 문제를 해결하기 위해 이러한 문제를 우아하게 해결할 수 있는 제네릭을 소개합니다. 제네릭은 객체 대신 전달된 데이터 유형 T를 사용합니다. 클래스가 인스턴스화될 때 T 유형이 지정됩니다. 런타임(런타임)이 자동으로 로컬 코드로 컴파일되며, 운영 효율성과 코드 품질이 크게 향상됩니다. . 안전.

C# 제네릭 사용

다음은 일반 데이터 유형 T를 자리 표시자로 사용하여 대신 인스턴스화 유형 중에 실제 값이 사용될 때까지 기다리는 제네릭을 사용하여 위 스택을 다시 작성하는 것입니다. 제네릭의 힘을 살펴보겠습니다.

public class Stack { (int i) { this.m_item = new T[i]; 클래스 작성 방법은 동일하게 유지됩니다. 데이터 유형 T는 모든 데이터 유형에 적용될 수 있으며 유형이 안전합니다. 이 수업의 호출 방법:

//인스턴스화는 int 유형의 클래스만 저장할 수 있음 Stack a = new Stack(100); 데이터 유형 int x = a.Pop() // 인스턴스화는 문자열 유형의 클래스만 저장할 수 있음 b = new Stack(100); b.Push(10); // 클래스 b는 문자열 유형 데이터만 수신하므로 이 행은 컴파일되지 않습니다. b.Push("8888"); 이 클래스는 다음으로 구현된 클래스와 완전히 다릅니다. 객체:

1. 유형이 안전합니다. int 유형의 스택이 인스턴스화되면 string 유형의 데이터를 처리할 수 없으며 다른 데이터 유형의 경우에도 마찬가지입니다.

2.박스를 포장하거나 접을 필요가 없습니다. 이 클래스가 인스턴스화되면 전달된 데이터 유형에 따라 로컬 코드가 생성됩니다. 로컬 코드 데이터 유형이 결정되었으므로 박싱 및 폴딩이 필요하지 않습니다.

3. 유형 변환이 필요하지 않습니다.

이론적 지식:

소위 제네릭: 매개변수화된 유형을 사용하여 동일한 코드에서 여러 데이터 유형을 작동합니다. 일반 프로그래밍은 보다 유연한 재사용을 달성하기 위해 "매개변수화된 유형"을 사용하여 유형을 추상화하는 프로그래밍 패러다임입니다.

C# 제네릭은 코드에 더 강력한 유형 안전성, 더 나은 재사용, 더 높은 효율성 및 더 명확한 제약 조건을 제공합니다.

C# 일반 기능은 런타임 시 CLR에서 지원됩니다. 이는 C++의 컴파일 타임 템플릿 메커니즘 및 Java의 컴파일 타임 "삭제 방법"과 다릅니다. 이를 통해 일반 기능이 CLR 지원 언어 간에 원활하게 상호 운용될 수 있습니다.

C# 일반 코드가 IL 및 메타데이터로 컴파일될 때 특수 자리 표시자는 일반 유형을 나타내는 데 사용되며 독점 IL 명령은 일반 작업을 지원하는 데 사용됩니다. 실제 일반 인스턴스화 작업은 JIT 컴파일 중에 "주문형" 방식으로 발생합니다.

C# 일반 컴파일 메커니즘은 다음과 같습니다.

컴파일의 첫 번째 라운드에서 컴파일러는 IL 코드의 "일반 버전"과 Stack 유형에 대한 메타데이터만 생성하며, 이를 생성하지 않습니다. 일반적인 유형의 인스턴스화를 수행하는 경우 T는 중간에 있는 자리 표시자 역할만 합니다.

JIT 컴파일 중에 JIT 컴파일러가 처음으로 Stack을 만나면 "일반 버전" IL 코드 및 메타데이터의 T --를 int 유형으로 대체하여 일반 유형을 인스턴스화합니다.

CLR은 유형 매개변수가 "참조 유형"인 모든 일반 유형에 대해 동일한 코드를 생성하지만, 유형 매개변수가 "값 유형"인 경우 CLR은 각각의 다른 "값 유형"에 대해 코드를 생성합니다. 암호.

C# 제네릭의 여러 기능

인스턴스화된 제네릭 유형의 매개변수가 동일한 경우 JIT 컴파일러는 유형을 재사용하므로 C#의 동적 제네릭 기능은 C++ 정적 템플릿을 방지하여 코드 팽창을 일으킬 수 있습니다. .

C# 제네릭 유형은 풍부한 메타데이터를 전달하므로 C#의 제네릭 유형은 강력한 리플렉션 기술에 적용될 수 있습니다.

C#의 제네릭은 "기본 클래스, 인터페이스, 생성자, 값 유형/참조 유형"의 제약 조건 메서드를 사용하여 유형 매개 변수에 대한 "명시적 제약 조건"을 구현합니다. 이는 유형 안전성을 향상시키지만 C++ 템플릿의 높은 유연성 기반을 잃게 됩니다. "서명"의 암시적 제약에 대해.

C# 일반 클래스가 컴파일되면 중간 코드 IL이 먼저 생성되고 일반 유형 T는 자리 표시자일 뿐입니다. 클래스를 인스턴스화할 때 T는 사용자가 지정한 데이터 유형으로 대체되며 JIT(Just-In-Time 컴파일러)에 의해 로컬 코드가 생성됩니다. 이 로컬 코드는 다음과 같습니다. 실제 유형으로 작성된 클래스이므로 다릅니다. 닫힌 클래스의 네이티브 코드가 다릅니다. 이 원칙에 따르면 다음과 같이 생각할 수 있습니다. 일반 클래스의 서로 다른 닫힌 클래스는 서로 다른 데이터 유형입니다.

이러한 방식으로 제네릭은 더욱 유연해질 뿐만 아니라 코드의 단순성과 단순성을 새로운 차원으로 끌어올립니다! 더 이상 다양한 오버로드된 메서드에 대한 특정 코드를 작성할 필요가 없습니다!

C# 제네릭은 개발 도구 분야에서 매우 귀중한 자산입니다. 세련되고 읽기 쉬운 구문을 통해 성능, 유형 안전성 및 품질을 향상시키고, 반복적인 프로그래밍 작업을 줄이고, 전체 프로그래밍 모델을 단순화합니다. C# 제네릭의 뿌리는 C++ 템플릿이지만 C#은 컴파일 타임 안전성과 지원을 제공하여 제네릭을 한 단계 더 발전시킵니다. C#은 2단계 컴파일, 메타데이터, 그리고 제약 조건 및 일반 방법과 같은 혁신적인 개념을 활용합니다. C#의 향후 버전에서는 새로운 기능을 추가하고 제네릭을 데이터 액세스 또는 지역화와 같은 다른 .NET Framework 영역으로 확장하기 위해 계속해서 제네릭을 발전시킬 것이라는 데는 의심의 여지가 없습니다.

이것이 C# 사용에 대한 이야기입니다. 제네릭에 대한 자세한 내용은 PHP 중국어 웹사이트(www.php.cn)를 참고하세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.