【C#진급 시리즈】07 방법

9898 단어
실례 구조와 인용 유형
이전 장에서는 참조 유형의 구성 프로세스를 설명했습니다.
우선, 무더기에서 인용 형식의 실례 대상에게 메모리를 분배한 다음, 대상의 추가 필드 (즉 형식 대상 바늘과 동기화 블록 인덱스) 를 초기화합니다.
이때 대상에게 분배된 메모리는 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 수식 문자를 섹션 방법 앞에 표시하는 것을 금지합니다.(이 점에서 유형 구조기와 유사)

좋은 웹페이지 즐겨찾기