첫날: C# 값 유형, 참조 유형, 포장 및 포장 해제

4335 단어
C#의 유형은 다음과 같습니다.
  • 값 유형(Value Type)
  • 참조 유형(Reference Type)
  • 값 형식과 인용 형식은 컴퓨터 메모리에서 어떻게 분배되는지에 따라 구분된다.
    값 유형은 구조와 매거진을 포함하고 값 유형은 특수한 값 유형을 포함하며 간단한 유형이라고 한다. 예를 들어 intbyte모든 값 유형은 암시적(C# 코드에서는 상속 관계를 볼 수 없지만 MSIL 코드를 통해서만 볼 수 있음) 상속System.ValueType,System.ValueType와 인용 유형은 모두 상속System.Object 기본 클래스에서 상속됩니다.
    Tips: C# 는 다중 상속을 지원하지 않으며 구조는 System에 암시적으로 상속됩니다.상속을 지원하지 않는 ValueType입니다.
    무엇이 퇴화창고입니까?
    더미와 창고의 개념:
  • 창고(Stack)는 후진선출의 데이터 구조로 메모리에서 변수가 창고에 분배되어 조작된다
  • 더미(heap)는 인용 유형의 실례(대상), 공간을 분배하는 메모리 영역으로 더미에 대상을 만들면 대상의 주소를 창고에 전달하는 변수(반대로 변수를 이 대상을 가리키거나 변수를 이 대상을 인용한다)-----즉 창고의 변수는 더미의 주소가 XXXX인 실례(대상)
  • 를 가리킨다.

    값 유형

    public struct ValPoint{
        public int x;  //         
    }
    ValPoint vPoint1; // ValPoint:     ,vPoint1:  ,          
    vPoint1.x = 10;  //       
    Console.WriteLine(vPoint1.x);   //      
    

    변수는 값 유형의 모든 필드를 포함하고 이 변수 vPoint1은 온라인 스택(Thread Stack)에 할당됩니다.
    Tips: 변수를 조작할 때만 변수가 입고됩니다.변수에 대한 조작은 사실상 일련의 출고와 입고 조작이다.

    구조적 특징1:


    정의된 구조 내의 모든 필드는 값을 초기화해야 합니다. 그렇지 않으면 '값을 부여할 수 있는 필드 x를 사용했습니다.' 라고 보고됩니다.왜냐하면.Net의 제약조건은 다음과 같이 모든 요소를 사용하기 전에 초기화해야 합니다.
    int i;
    Console.WriteLine(i);  //       ,    int                
    

    구조적 특징2:


    구조 내의 방법을 호출하기 전에 구조 내의 모든 필드에 값을 부여해야 한다
    //   ValPoint  
    public struct ValPoint{
        public int x;
        public void Block( ){ }
    }
    //          
    ValPoint vPoint1;
    // vPoint1.x = 200;  //      vPoint1     x    ,      
    vPoint1.Block();  //           vPoint1
    Console.WriteLine(vPoint);    //           vPoint1
    

    Tips: 구조에 둘 이상의 필드가 있는 경우 둘 이상의 필드에 값을 지정해야 합니다.
    Q:위의 예에서 구조 내 방법은 필드 x를 사용하지 않았는데 왜 초기화 값을 해야 합니까?이렇게 한 후에 만약 구조에 몇 개의 필드가 있다면 초기화 할당을 하는 것이 번거롭지 않겠는가?A:컴파일러는 구조 유형에 대해 은밀하게 무참한 접근 함수를 생성합니다. 이 구조 함수에서 구조 구성원을 초기화하고 모든 값 유형에 0 또는 0의 값을 부여하며 인용 유형에null 값을 부여합니다. 따라서 Struct 유형은 무참수의 구조 함수를 스스로 설명할 수 없기 때문에 은밀하게 설명하는 구조 함수를 통해ValPoint 형식 변수를 생성합니다.
    ValPoint vPoint1 = new ValPoint();
    Console.WriteLine(vPoint1.x);   //     0
    

    참조 유형


    인용 형식 변수를 설명하고 new 조작부호를 사용하여 인용 형식의 실례를 만들 때 인용 형식의 변수는 스레드 창고에 분배됩니다. 이 변수는 무더기에 있는 인용 형식의 실례 메모리 주소만 저장하고 변수 자체는 어떤 형식의 데이터도 포함하지 않습니다.
    변수만 정의하고 new 조작부호를 사용하지 않으면 무더기에 형식을 만드는 실례가 없기 때문에 이 변수의 값은null로 대상을 가리키지 않습니다. (무더기 대상의 실례)
    Tips: 혼동하기 쉬운: 변수(Variable), 객체(Object), 인스턴스(Instance).변수는 값 유형일 수도 있고 인용 유형일 수도 있다. 인용 유형이라면 그 자체가 실례 대상에 대한 인용(메모리 주소)만 포함하기 때문에 대상 인용이라고도 부른다.무더기에 만들어진 대상을 대상의 실례라고 부른다.
    public class RefPoint{
        public int x;
    
        public RefPoint(int x){this.x = x;}
        public RefPoint(){}
    }
    

    다음 선언문만 쓸 경우:
    RefPoint rPoint1;  //                 ,        (       )   
    

    new 조작부호를 사용할 때:
    rPoint1 = new RefPoint(1);
    
  • 응용 프로그램 더미에 인용 형식 대상을 만들고 메모리 주소를 분배합니다
  • .
  • 이 실례의 인용을 구조 함수에 자동으로 전달한다(이렇기 때문에 구조 함수에서this를 사용하여 이 실례에 접근할 수 있다)
  • 이 유형의 구조 함수 호출
  • 이 실례의 인용 메모리 주소를 되돌려주고 rPoint1 변수에 복사합니다. 이 rPoint 인용 대상이 저장한 데이터는 더미에 변형된 형식을 만드는 실례 주소를 가리킵니다.

  • 단순 유형


    두 int 형식이 같은지 비교하려면 보통 다음과 같습니다.
    int i = 3;
    int j = 3;
    if(i == j){ Console.WriteLine("i equals to j");}
    

    그러나 구조와 같은 사용자 정의 참조 유형은 "=="을 사용하여 동일한지 여부를 판단할 수 없으며 Equals() 방법이 필요합니다.
    string 유형은 다음과 같은 참조 유형입니다.
    string a = "123";
    string b = "123";
    if(a == b){Console.WirteLine("a equals to b");}
    

    비교되는 것은 그들이 같은 대상을 쌓아 올리는 것을 가리키는지 여부다.위에서 분명히 다르지만 그들이 포함하는 수치가 같기 때문에string 유형에 대해'=='로 비교하면 실제로는 인용 유형에 포함된 값을 비교하는 것이지 인용하는 것이 아니다.

    포장과 해체

  • 포장: 값 유형 -> 등가의 인용 유형
  • int i = 1;
    Object boxed = i;
    Console.WriteLine("Boxed Point:" + boxed);
    
  • 더미에 새로운 대상의 실례를 위해 메모리를 분배한다.이 대상의 실례는 데이터를 포함하지만 이름이 없다.
  • 창고의 값 유형 변수의 값을 더미의 대상에 복사
  • 무더기로 만든 대상의 주소를 인용 형식 변수에 되돌려줍니다
  • 풀기: 포장된 인용 유형 -> 값 유형
  • int i = 5;
    Object boxed = i;
    j = (int) boxed;
    Console.WriteLine("UnBoxed Point : " + j);
    
  • 포장된 객체의 주소 가져오기
  • 더미의 대상에서 더미의 값 변수로 값을 복사
  • 이를 통해 알 수 있듯이 포장과 해체는 반복적으로 더미 위에서 조작해야 하기 때문에 프로그램에서 무의미한 포장과 해체를 최대한 피해야 한다.

    좋은 웹페이지 즐겨찾기