C\#범 형 을 자세히 소개 합 니 다.

9864 단어 c#범 형
C\#개발 에 서 는 범 형 을 적 게 사용 해 서 는 안 된다.범용 은.NET 2.0 버 전 으로 C\#프레임 워 크 에서 용기 의 사용 에 광범 위 하 게 응용 된다.다음은 우리 가 상세 하 게 소개 하 겠 습 니 다.
1.범 형의 주요 장점
1.성능 이 더 좋다.
2.유형 이 더 안전 하 다.
3.코드 의 더 많은 재 활용 과 확장 성.
2.일반적인 기본 사용
범 형의 주요 장점 중 하 나 는 성능 이다.우 리 는 다음 과 같은 예 를 살 펴 보 자.

static void Main(string[] args)
  {
   //        
   ArrayList list = new ArrayList();
   //            
   list.Add(12);
   //       12     
   int num = (int)list[0];
   Console.WriteLine(num);
   Console.WriteLine("    ");
   Console.ReadKey();
  }
메타 데이터 에서 ArrayList 클래스 의 Add 방법

//
  //   :
  //         System.Collections.ArrayList     。
  //
  //   :
  // value:
  //       System.Collections.ArrayList     System.Object。      null。
  //
  //     :
  //  value      System.Collections.ArrayList   。
  //
  //   :
  // T:System.NotSupportedException:
  //  The System.Collections.ArrayList is read-only.-or- The System.Collections.ArrayList
  //  has a fixed size.
  public virtual int Add(object value);

모두 가 알 고 있 을 것 이 라 고 믿 습 니 다.포장 상 자 를 뜯 을 때 성능 이 비교적 손실 되 는 것 입 니 다.add 방법 을 실행 할 때 값 유형 을 인용 유형(포장)으로 바 꾸 고 꺼 낼 때 상 자 를 뜯 는 것 입 니 다.그러면 어떻게 해 야 이런 상황 을 피 할 수 있 습 니까?
다음 코드 를 보 겠 습 니 다:

//     
   List<int> list = new List<int>();
   list.Add(12);
   int num = list[0];
   Console.WriteLine(num);
   Console.WriteLine("    ");
   Console.ReadKey();
이때 코드 는 상자 분해 작업 이 일어나 지 않 았 다.
메타 데이터 에서 List 클래스 의 Add 방법

//
  //   :
  //         System.Collections.Generic.List`1     。
  //
  //   :
  // item:
  //       System.Collections.Generic.List`1      。      ,      null。
  public void Add(T item);

코드 를 여기에 썼 을 때,우 리 는 단지 List 범 형 집합 을 만 들 었 을 뿐이다.너 는 범 형 우위 가 도대체 어디 에 있 는 지 아직 느끼 지 못 할 수도 있 고,범 형 이 도대체 어떻게 사용 되 는 지 모 를 수도 있다.자,다음은 테스트 와 자신의 실제 응용 예 를 쓰 겠 습 니 다.
arraylist 와 list 집합 성능 테스트

static void Main(string[] args)
  {
   //        
   ArrayList arylist = new ArrayList();
   //            

   //     
   List<int> list = new List<int>();


   //   
   Stopwatch watch = new Stopwatch();
   watch.Start();//    
   for (int i = 0; i < 10000000; i++)
   {
    arylist.Add(i);
   }
   watch.Stop();
   Console.WriteLine("Arraylist  :"+watch.ElapsedMilliseconds);

   Stopwatch watch1 = new Stopwatch();
   watch1.Start();//    
   for (int i = 0; i < 10000000; i++)
   {
    list.Add(i);

   }
   watch1.Stop();
   Console.WriteLine("list  :" + watch1.ElapsedMilliseconds);
   Console.WriteLine("    ");
   Console.ReadKey();
  }

실행 결과:

이상 의 예 에서 시간 을 재 는 과정 에서 코드 가 중복 되 었 음 을 알 수 있 습 니 다.이 문 제 를 어떻게 해결 하 는 지 팬 형 은 도움 이 될 것 입 니 다.
같은 조작(모두 순환 적 으로 요 소 를 추가 하고 계산 할 때)이 같은 방법 으로 이 루어 지면 ok 이 아 닙 니까?다만 이 방법 은 일반적인(Array List 를 받 아들 일 수도 있 고 List 를 받 아들 일 수도 있 습 니 다)입 니 다.다음은 이 방법 을 쓰 겠 습 니 다.  

//   T     
  public static long GetTime<T>(T t)
  {
   Stopwatch watch = new Stopwatch();
   watch.Start();//    
   for (int i = 0; i < 10000000; i++)
   {
    t.Add(i);
   }
   watch.Stop();
   return watch.ElapsedMilliseconds;
  }
하지만 문제 가 생 겼 습 니 다.여기 에는 Add 방법 이 없 군요.우리 의 사고방식 은 이 T 를 호출 할 때 Array List 유형 으로 도 사용 할 수 있 고 List 유형 으로 도 사용 할 수 있다 는 것 이다.여기 서 일반적인 제약 을 설계 했다.
3.범 형 제약
범 형 을 사용 할 때 이 범 형 유형의 방법 을 호출 하려 면 제약 을 추가 해 야 합 니 다.범 형 제약 은 주로 다음 과 같은 몇 가지 가 있다.
구속 하 다
설명 하 다.
where T:struct
구조 에 대한 제약 조건 은 T 가 값 유형 이 어야 합 니 다.
where T:class
T 는 인용 형식 이 어야 합 니 다.
where T:ITest
T 는 ITest 인 터 페 이 스 를 실현 해 야 합 니 다.
where T:Test
T 는 기본 테스트 를 계승 해 야 합 니 다.
where T:new()
T 는 기본 구조 함수 가 있어 야 합 니 다.
where T:T2
T 파생 자 범 형 T2,누 드 타 입 구속 이 라 고도 함
우 리 는 다음 일반적인 방법 으로 수정 했다.Array List 와 List 는 모두 인터페이스 IList 를 실현 했다.이때 우 리 는 이 인터페이스 제약 을 추가 했다.

//   T     
  public static long GetTime<T>(T t)where T:IList
  {
   Stopwatch watch = new Stopwatch();
   watch.Start();//    
   for (int i = 0; i < 10000000; i++)
   {
    t.Add(i);
   }
   watch.Stop();
   return watch.ElapsedMilliseconds;
  }
호출 결과:

코드 를 여기에 쓸 때 범 형 에 대해 이미 알 고 있다 고 믿 지만 앞으로 의 논리 프로 그래 밍 에 응용 하려 면 반드시 정 리 를 잘 해 야 한다.같은 유형의 똑 같은 방법 이나 업무 논리 가 같 거나 특정한 판단 만 다 르 면 범 형 을 사용 할 수 있 고 효율 적 일 뿐만 아니 라 코드 의 양 도 적다.
4.응용 장면 시범
우리 의 프로젝트 개발 에서 데이터 뱅 크 의 삭제 와 검 사 는 반드시 없어 서 는 안 될 것 이다.여기 서 우 리 는 범 형 으로 삭제 와 검 사 를 하 는 범 형 류 를 정의 한다.그 다음 에 하나의 사용자 표(실제 응용 에서 대응 하 는 데이터 베이스 중의 표 구조)를 만 들 고 데이터 베이스 중의 모든 표 는 일반적인 유형 에서 정의 하 는 방법 을 사용 할 수 있 으 며 모든 것 을 추가 삭제 하고 검사 작업 을 할 필요 가 없 으 며 대상 을 대상 으로 프로 그래 밍 하 는 사상 이기 도 한다.

public class BaseDal<T>where T:class ,new ()
 {
  //         
  public void Query(int id) {
   Console.WriteLine(typeof(T).Name+"    ,id="+id);
  }
  
  public void Update(T t) {

   Console.WriteLine(typeof(T).Name+"    ");
  }
  public void Delete(T t)
  {
   Console.WriteLine(typeof(T).Name + "    ");
  }

  public void Add(T t) {
   Console.WriteLine(typeof(T).Name + "    ");
  }
 }

public class User
 {
  public int Id { get; set; }
  public string Name { get; set; }
 }
호출 시범

BaseDal<User> dal = new BaseDal<User>();
   var user = new User()
   {
    Id = 0,
    Name = "  1"
   };
   dal.Add(user);
   dal.Query(0);
   user.Name = "  11";
   dal.Update(user);
   dal.Delete(user);

   Console.ReadKey();

5.범 형의 협 변 과 항 변
협 변 과 항 변 은 주로 매개 변수 와 반환 값 의 유형 을 변환 합 니 다.NET 4 이후 협 변 과 항 변 을 통 해 범 형 인터페이스 나 이 범 형 의뢰 를 통 해 이 확장 을 추가 할 수 있 습 니 다.
현재 우 리 는 두 가지 종류의 Shape(모양),Rectangle(사각형 류),Rectangle 파생 자체 Shape 를 쓰 고 하나의 방법 을 씁 니 다 Public static Rectangle GetRec().이 럴 때 방법의 범 형 유형 은 변 하지 않 는 다 는 것 을 알 게 될 것 이다.바로 내 가 하나의 유형 을 Rectangle 로 되 돌려 주 는 것 이다.그러나 나 는 Shape 로 받 아들 일 수 있 지만 범 형 은 NET 4.0 이전에 이 방식 을 지원 하지 않 았 다.범 형 은 NET 4.0 이후 에 범 형 인터페이스 와 범 형 의뢰 를 지원 하 는 협 변 과 변 화 를 제공 했다.
일반 방법 변경 방지 코드 설명

//  
 public class Shape
 {
  public double Width { get; set; }
  public double Height { get; set; }

  public override string ToString()
  {
   return string.Format("width:{0},height:{1}",Width,Height);
  }
 }

 //  
 public class Rectangle : Shape {

 }

///-----------------------------------     

public static Rectangle GetRec() {
   return new Rectangle();
  }
 Shape s = GetRec();
   Console.ReadKey();
1.범용 인터페이스의 협동
범 형 인 터 페 이 스 는 유형 T 앞 에 out 키 워드 를 추가 합 니 다.이때 범 형 인 터 페 이 스 는 협 변 된 것 입 니 다.즉,반환 유형 은 T 일 수 밖 에 없다 는 것 을 의미 합 니 다.코드 직접 보기:

//       
 public interface IIndex<out T>
 {
  T GetT(int index);
  int Count { get; }
 }


 public class RecCollection : IIndex<Rectangle>
 {
  private Rectangle[] data = new Rectangle[2] {
   new Rectangle() { Width=10,Height=20 },
   new Rectangle() {Width=20,Height=30 }
  };


  public int Count
  {
   get
   {
    return data.Count();
   }
  }

  public Rectangle GetT(int index)
  {
   return data[index];
  }
 }

//     
  Shape s1 = new RecCollection().GetT(1);
   Console.WriteLine(s1.ToString());

   IIndex<Rectangle> rec = new RecCollection();
   IIndex<Shape> shapes = rec;
   for (int i = 0; i < shapes.Count; i++)
   {
    Console.WriteLine(shapes.GetT(i));
   }
   Console.ReadKey();
상기 코드 를 통 해 알 수 있 듯 이 우 리 는 범 형 인터페이스의 범 형 을 직사각형(Rectangle)으로 정의 하지만 받 아들 일 때 기본 클래스(Shape)를 사용 하여 여기 서 협 변 을 실현 했다.
2.범용 인터페이스의 변형 저항
만약 에 범 형 유형 이 in 키워드 로 표시 된다 면 이 범 형 인 터 페 이 스 는 변 하지 않 는 것 이다.그러면 인 터 페 이 스 는 범 형 T 를 그 방법의 입력 으로 만 사용 할 수 있다.

//       
 public interface IDisplay<in T>
 {
  void Show(T item);
 }

 public class ShapeDisplay : IDisplay<Shape>
 {
  public void Show(Shape item)
  {
   Console.WriteLine(item);
  }
 }
//-------------------------    ------
  Rectangle recs = new Rectangle() { Width=100,Height=200};
  IDisplay<Shape> shapeDisplay = new ShapeDisplay();
  shapeDisplay.Show(recs);

  IDisplay<Rectangle> recDisplay = shapeDisplay;
  recDisplay.Show(recs);
  Console.ReadKey();
상기 코드 를 통 해 알 수 있 듯 이 범 형 도 항 변 과 협 변 을 지원 한다.
총화
범 형 은 C\#언어 발전 이 가 져 온 새로운 방법 입 니 다.상기 예 는 간단 한 운용 일 뿐 입 니 다.여러분 들 은 상기 예 를 통 해 시사 점 을 주 고 프로젝트 에서 범 형 을 더욱 잘 사용 할 수 있 기 를 바 랍 니 다.이상 은 팬 캐 시가 있 습 니 다.여러분 이 관심 이 있 으 면 자 료 를 찾 아 보 세 요.오늘 은 여기까지 하 겠 습 니 다.말 하지 않 은 것 도 있 고 안 좋 은 점 도 있 습 니 다.여러분 의 지적 을 환영 합 니 다!
이상 은 C\#범 형의 상세 한 내용 을 상세 하 게 소개 하 는 것 입 니 다.C\#범 형 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기