【C#진급 시리즈】07 방법
이전 장에서는 참조 유형의 구성 프로세스를 설명했습니다.
우선, 무더기에서 인용 형식의 실례 대상에게 메모리를 분배한 다음, 대상의 추가 필드 (즉 형식 대상 바늘과 동기화 블록 인덱스) 를 초기화합니다.
이때 대상에게 분배된 메모리는 0으로 직접 설정되어 있기 때문에 사용하는 구조기에서 대상의 일부 필드를 처리하지 않으면 이 필드의 초기 값은 0이나null이어야 한다.
만약 하나의 클래스가 구조 함수가 없다면, 이 클래스 구조가 있을 때 기본 무참구조기를 정의할 것이다. 그 안에 기류의 무참구조기를 간단하게 호출할 것이다.
극소수의 경우, MemberwiseClone 방법 (깊이 복사) 과 반서열화 대상을 만드는 데 실용적이지 않은 실례 구조기가 있을 수 있다.(역서열화는 GetUnitializedObject나 GetSafeUninitializedObject 방법을 호출하여 대상에게 메모리를 분배합니다. 나중에 말씀하십시오.)
인라인 초기화로 인해 성능 문제가 발생할 수 있다는 것을 기억하십시오.
매번 내연 초기화는 실제적으로 이 초기화 필드의 조작을 구조 함수의 코드에 끼워 넣기 때문이다(이런 조작을 먼저 한 다음에 진정한 구조 함수의 조작을 할 수 있음을 주의하라).만약 구조기 함수 하나만 있다면 아무런 영향도 없을 것이다.그러나 만약 여러 개의 구조기 함수가 있다면, 이 구조기 함수에는 이 초기화 필드의 코드가 삽입될 것이다.
그래서 여러 개의 구조기 파라미터가 존재하고 코드에 내부 연결이 초기화되면 실제 생성된 코드에는 대량의 불필요한 코드가 있을 것이다.다음과 같은 방법으로 해결할 수 있습니다.
public class Troy{
//
int _a;
int _b;
public Troy() {
// ,
this._a = 1;
this._b = 2;
}
public Troy(int i):this() // , this()
{
}
public Troy(int i,int j) : this()
{
}
}
인스턴스 구조 및 값 유형
값 유형은 사실 구조기를 정의할 필요가 없고 C#컴파일러도 값 유형에 기본적인 무참구조기를 내장하지 않는다.
인용 형식에 끼워 넣은 값 형식만 0 또는null로 초기화됩니다. 창고 기반 값 형식이라면 읽기 전에 강제로 초기화해야 합니다. 그렇지 않으면 오류가 발생합니다.
값 형식의 실례 구조기는 현식 호출만 사용할 수 있습니다. 그렇지 않으면 필드가 0 또는null로 초기화됩니다.(즉, 즉시 이 struct에는 무참구조 함수가 있다. 호출을 표시하지 않으면 무참구조 함수를 자동으로 호출하지 않는다. 실제로 C#컴파일러도 구조체에 무참구조 함수를 쓰는 것을 허락하지 않는다. 왜냐하면 이 점에서 너무 쉽기 때문이다.
C#에서는 값 유형이 참조되지 않은 구조 함수를 정의하는 것을 허용하지 않으므로 값 유형도 인라인 매개변수화할 수 없습니다.(정적 필드는 내부 연결을 초기화할 수 있습니다. 왜냐하면 유형 대상이 아니라 실례 대상이기 때문입니다.)
또한 값 형식의 모든 구조 함수는 초기화할 때 값 형식의 모든 필드에 값을 부여해야 한다.
이렇게 번거로운 설정에 대해서도 당연히 해결할 방법이 있다.
public struct Troy {
public int a;
public int b;
public Troy(int i) {
this = new Troy();// 0 null
//
a = i;
}
}
(나는 방금 VS로 값 매개 변수를 초기화한 작은 예를 썼는데 360이 바이러스로 삭제되었다는 것을 토로하지 않을 수 없었다.)
유형 구조자 정보
우선 유형 구조기는 사실상 CLR 분배 메모리의 유형 대상을 초기화할 때 사용하는 것임을 알아야 한다.
유형 구조기는 매개 변수가 있는 것을 허용하지 않으며, 당연히 하나의 유형 구조 함수만 정의할 수 있다.
실제로 유형 구조기는 반드시 개인적이어야 하며, 심지어private 수식자를 현식으로 쓰는 것도 허용하지 않는다. 이렇게 하는 것은 개발자의 호출을 방지하기 위해서이다.호출은 항상 CLR에서 수행합니다.
간단한 예:
class Program
{
static void Main(string[] args)
{
Troy obj = new Troy();
}
}
public class Troy {
static Troy() {
Console.WriteLine(" 6 6?");
}
}
구성 프로세스:
JIT 컴파일러는 메서드를 컴파일할 때 코드가 참조하는 유형을 확인합니다.어떤 유형이든 유형 구조기를 정의하면 JIT 컴파일러는 현재 AppDomain에 대해 이 유형 구조기를 실행했는지 검사합니다.예컨대 호출하지 않고, 그렇지 않으면 호출한다.CLR은 모든 AppDomain에서 하나의 유형 구조기를 한 번만 실행하기를 원하기 때문에 여러 개의 라인이 동시에 유형 구조기를 호출하지 않도록 하기 위해서 첫 번째 유형 구조기의 라인을 호출할 때 서로 밀어내는 라인 동기화 자물쇠를 가져옵니다.이렇게 되면 단지 하나의 라인만 호출할 수 있다. 뒤의 라인을 사용할 때 이미 호출된 것을 발견하면 유형 구조기를 다시 호출하지 않을 것이다.(유형 구조기의 라인이 안전하기 때문에 그 안에서 모든 단일 대상을 초기화하는 데 적합하다.)
값 유형에서 유형 구조 함수를 정의할 수 있지만 실제로는 값 유형이 무더기에 유형 대상이 없기 때문에 자연히 안의 코드가 호출되지 않는다.
연산자 재부팅 정보
실제 CLR은 프로그래밍 언어의 문법이기 때문에 조작부호 재부팅에 대해 아무것도 모른다.
C# 같은 언어로 작성된 연산자 리셋 명령문이 IL 코드로 컴파일되었을 때, 사실은specialname 로고가 있는 함수가 되었다.
컴파일러가 + 라는 조작부호를 보았을 때, 몇 개의 조작수 유형에서op 라고 정의되었는지 볼 수 있습니다Addition 함수(컴파일된 실제 함수 이름)와 메소드 매개 변수는 작업 수 유형과 호환됩니다.
따라서 연산자 재부팅 함수에는 이 재부팅 방법을 결정하는 유형과 같은 매개 변수가 있어야 합니다.
public class Troy {
public static int operator +(Troy a, Troy b) {
return 10;
}
}
변환 연산자 방법 정보
class Program
{
static void Main(string[] args)
{
Troy obj = 3;//
string a = obj;// ,
string a =(String)obj;//
}
}
public class Troy {
// implicit
public static implicit operator Troy(Int32 num) {
return new Troy();
}
// explicit
public static explicit operator String(Troy troy)
{
return " ";
}
}
일반적인 +-이런 조작부호가 다시 불러오는 것과 같이 실제로 생성된 IL 코드에는 이름이 바뀌었고 접두사에op 가 붙었다.
C#컴파일러가 코드의 한 대상이 다른 유형의 다른 대상을 원한다는 것을 알았을 때, 이 두 종류에 스텔스 변환이 정의된op 가 있는지 다시 찾습니다.Implicit 메서드, 예, 바로 갑니다.유사함을 표시합니다.
Decimal류의 정의를 참고하여 이해할 수 있습니다.
확장 방법 정보
먼저 나의 인식을 말해 보아라. 사실 나는 이 물건을 사용하는 것을 건의하지 않는다.
규범에 맞지 않게 쓴 확장 방법 때문에 코드의 읽기 난이도가 높아지고 유지보수 원가가 높아진다.(나는 어떤 사람이 이 물건을 곳곳에 다 쓸 것이라고 정말 확신한다)
이 물건은 앞서 《재구성》을 쓴 학습노트에서 언급한 바와 같이 주로 다른 사람이 봉인된 라이브러리를 해결하는 데 쓰이기 때문에 자신이 원하는 함수를 늘릴 수 없다.
19시.불완전한 라이브러리에서 말한
간단하게 말하면, 역시 신중하게 쓰고, 자신이 쓴 종류는 확장하는 방법을 쓰지 마라.
또한 확장 방법은 최고급 정적 클래스에서 정의된 정적 방법이어야 합니다. 플러그인 클래스에서 컴파일하면 오류가 발생합니다.
실제로 확장 방법은 C#컴파일러가 컴파일한 후에도 일반적인 정적 대상의 정적 함수일 뿐이고 [Extension]의 특성을 추가했을 뿐이다.그러나 실제로 이 Extension Attribute 기능은 코드에서 사용할 수 없습니다. 모두 C#컴파일러가 자동으로 생성한 것입니다.
분부 방법에 관하여
분부 방법은 분부류와 비슷하지만 방법 앞에 파티얼 수식자를 붙인다.
이렇게 하면 다른 부분류가 이 방법을 실현했다면 이 방법을 추가할 것이고 실현되지 않았다면 이 코드는 컴파일할 때 무시될 것이다.
그러나 섹션 방법은 섹션 클래스와 구조에서만 사용할 수 있고, 되돌아오는 형식은 항상void이며, 어떤 매개 변수도out로 수식할 수 없습니다.이렇게 제한되는 것은 방법이 운행할 때 존재하지 않을 수도 있고 되돌아오지 않을 수도 있기 때문이다.
섹션 방법은 항상 private이지만, C# 컴파일러는 private 수식 문자를 섹션 방법 앞에 표시하는 것을 금지합니다.(이 점에서 유형 구조기와 유사)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.