C\#가 변 하지 않 는 유형 깊이 분석

8525 단어 C#
C\#를 배 운 사람 은 모두 string 유형 을 알 고 있 지만 string 은 특수 한 인용 유형 으로서 또 하나의 중요 한 특징 은 항정 성 또는 불가 변성,즉 Immutable 이다.가 변 적 이지 않 은 유형 으로서 가장 중요 한 특징 은 만 들 면 위탁 관리 더미 에 새로운 대상 인 스 턴 스 를 만 들 고 이전 대상 인 스 턴 스 와 인접 하여 위탁 관리 더미 에 연속 적 인 메모리 공간 을 분배 하 는 것 이다.
그렇다면 왜 가 변 적 이지 않 은 타 입 이 필요 할 까?
다 중 스 레 드 상황 에서 한 스 레 드 는 여러 가지 원인(예 를 들 어 이상)으로 인해 한 변수 가 대표 하 는 유형의 일부 구성원 의 값 만 수정 했다.이때 다른 프로 세 스 가 들 어 와 도 이 변 수 를 방문 했다.두 번 째 프로 세 스 가 방문 한 변수 구성원 은 일부 구성원 은 원래 의 값 이 고 다른 구성원 의 값 은 첫 번 째 스 레 드 가 수정 한 값 이다.이렇게 해서 데이터 가 일치 하지 않 는 다.가 변 적 이지 않 은 유형 은 다 중 스 레 드 조건 에서 의'데이터 불일치'문 제 를 해결 하기 위 한 것 이다.
물론 문자열 의 불변성 이나 항상성 은'데이터 불일치'문 제 를 해결 할 뿐만 아니 라 문자열 의'상주'에 전 제 를 제공 해 야 서로 다른 문자열 과 위탁 관리 더미 의 메모리 주 소 를 키 값 쌍 의 형식 으로 전체 해시 표 에 넣 을 수 있 습 니 다.
1.'데이터 가 일치 하지 않 음'을 직접 목격 한다.
Student 의 Score 속성 에 대해 서 는 값 을 부여 할 때 검 사 를 더 해 두 자릿수 정수 인지 확인 합 니 다.

  public struct Student
  {
    private string name;
    private string score;
 
    public string Name
    {
      get { return name; }
      set { name = value; }
    }
 
    public string Score
    {
      get { return score; }
      set
      {
        CheckScore(value);
        score = value;
      }
    }
 
    //       2    
    private void CheckScore(string value)
    {
      string pattern = @"\d{2}";
      if (!Regex.IsMatch(value, pattern))
      {
        throw new Exception("      !");
      }
    }
 
    public override string ToString()
    {
      return String.Format("  :{0},  :{1}", name, score);
    }
  }
 
주 프로그램 에서 일부러 이상 을 만 들 었 는데,그 목적 은 하나의 변수 가 대표 하 는 유형의 일부 구성원 에 게 만 값 을 부여 하 는 것 이다.

    static void Main(string[] args)
    {
      Student student = new Student();
      student.Name = "  ";
      student.Score = "80";
      Console.WriteLine(student.ToString());
 
      try
      {
        student.Name = "  ";
        student.Score = "8";
      }
      catch (Exception)
      {
        
        throw;
      }
      Console.WriteLine(student.ToString());
      Console.ReadKey();
    }
 
중단 점,실행,Student 형식의 student 변 수 를 발 견 했 습 니 다.두 번 째 할당 에서 student 의 Name 속성 값 을 바 꾸 었 고 student 의 Score 속성 은 이상 이 발생 하여 수정 되 지 않 았 습 니 다.이것 이 바로 데이터 가 일치 하지 않 는 다 는 것 이다.
다음 그림 에서 보 듯 이:

2.디자인 불가 변 유형
1.불 가 변 유형의 2 가지 특성:
① 대상 의 원자 성:바 꾸 지 않 거나 바 꾸 려 면 모든 구성원 을 바 꾸 어 새로운 대상 을 만든다.
② 대상 의 상수 성:대상 이 생 성 되면 상 태 를 바 꿀 수 없다.즉,대상 의 속성 을 바 꿀 수 없고 새로운 대상 만 만 만 들 수 있다.
2.상기 불 가 변 유형의 2 가지 특징 에 따른다.
① 구조 함수 에서 모든 필드 에 값 을 부여 한다.
② 속성 에 있 는 set 접근 기 를 삭제 합 니 다.

  class Program
  {
    static void Main(string[] args)
    {
      Student student = new Student("  ", "90");
      student = new Student("  ","80");
      Console.WriteLine(student.ToString());
      Console.ReadKey();
    }
  }
 
  public struct Student
  {
    private readonly string name;
    private readonly string score;
 
    public Student(string name, string score)
    {
      this.name = name;
      this.score = score;
    }
 
    public string Name
    {
      get { return name; }
    }
 
    public string Score
    {
      get { return score; }
    }
 
    public override string ToString()
    {
      return String.Format("  :{0},  :{1}", name, score);
    }
  }
 
실행 결 과 는 다음 그림 과 같 습 니 다.

이 를 통 해 알 수 있 듯 이 우 리 는 Student 의 한 구성원 을 수정 할 수 없고 구조 함 수 를 통 해 새로운 대상 을 만들어'대상 의 원자 성'을 만족 시 킬 수 밖 에 없다.
또한 Student 대상 인 스 턴 스 의 특정한 속성 값 을 수정 할 수 없 으 며'대상 의 상수 성'에 부합 합 니 다.
3.인용 형식 필드 와 속성 이 있다 면 어떻게'불가 변성'을 할 수 있 습 니까?

  class Program
  {
    static void Main(string[] args)
    {
      string[] classes = {"  ", "  "};
      Student student = new Student("  ", "85", classes);
      Console.WriteLine("==    ==");
      Console.WriteLine(student.ToString());
 
      string[] tempArray = student.Classes;
      tempArray[0] = "  ";
      Console.WriteLine("==    ==");
      Console.WriteLine(student.ToString());
      Console.ReadKey();
    }
  }
 
  public struct Student
  {
    private readonly string name;
    private readonly string score;
    private readonly string[] classes;
 
    public Student(string name, string score, string[] classes)
    {
      this.name = name;
      this.score = score;
      this.classes = classes;
    }
 
    public string Name
    {
      get { return name; }
    }
 
    public string Score
    {
      get { return score; }
    }
 
    public string[] Classes
    {
      get { return classes; }
    }
 
    public override string ToString()
    {
      string temp = string.Empty;
      foreach (string item in classes)
      {
        temp += item + ",";
      }
 
      return String.Format("  :{0},  :{1},      :{2}", name, score,temp.Substring(0, temp.Length -1));
    }
  }
 
결 과 는 다음 그림 과 같다.

이 를 통 해 알 수 있 듯 이 대상 의 속성 에 대해 간접 적 으로 할당 을 수정 할 수 있 고 가 변 적 이지 않 은 유형의'상수 성'특징 을 만족 시 키 지 못 한다.
4.구조 함수 와 속성의 get 접근 기 에서 복사 하 는 방식 으로 불변성 만족

  class Program
  {
    static void Main(string[] args)
    {
      string[] classes = {"  ", "  "};
      Student student = new Student("  ", "85", classes);
      Console.WriteLine("==    ==");
      Console.WriteLine(student.ToString());
 
      string[] tempArray = student.Classes;
      tempArray[0] = "  ";
      Console.WriteLine("==    ==");
      Console.WriteLine(student.ToString());
      Console.ReadKey();
    }
  }
 
  public struct Student
  {
    private readonly string name;
    private readonly string score;
    private readonly string[] classes;
 
    public Student(string name, string score, string[] classes)
    {
      this.name = name;
      this.score = score;
      this.classes = new string[classes.Length];
      classes.CopyTo(this.classes, 0);
      CheckScore(score);
    }
 
    public string Name
    {
      get { return name; }
    }
 
    public string Score
    {
      get { return score; }
    }
 
    public string[] Classes
    {
      get
      {
        string[] result = new string[classes.Length];
        classes.CopyTo(result,0);
        return result;
      }
    }
 
    //       2    
    private void CheckScore(string value)
    {
      string pattern = @"\d{2}";
      if (!Regex.IsMatch(value, pattern))
      {
        throw new Exception("      !");
      }
    }
 
    public override string ToString()
    {
      string temp = string.Empty;
      foreach (string item in classes)
      {
        temp += item + ",";
      }
 
      return String.Format("  :{0},  :{1},      :{2}", name, score,temp.Substring(0, temp.Length -1));
    }
  }
 
실행 결 과 는 다음 그림 과 같 습 니 다.

그 밖 에 점수 가 조건 을 만족 시 키 지 못 하면 Student=new Student('장 삼','8',classes)는 잘못 보고 합 니 다.

좋은 웹페이지 즐겨찾기