C\#반사 와 dynamic 최 적 조합 예시 코드

9534 단어 cdynamic반사
C\#에서 반사 기술 이 광범 위 하 게 응용 되 고 반사 가 무엇 인지.....................................................................광고:제 글 을 좋아 하 는 친구 가 제 블 로그 에 관심 을 가 져 주세요.이것 도 제 글 쓰기 의 동력 을 향상 시 키 는 데 도움 이 됩 니 다.
반사:미녀 나 잘 생 긴 남 자 를 등지 고 뒤 돌아 보지 못 하고 자세히 관찰 할 때(순 전 히 허구 이다.우연 이 있 으 면 순 전 히 비슷 하 다)작은 거울 하나 가 당신 의 요 구 를 만족 시 킬 수 있다.C\#프로 그래 밍 과정 에서 도 비슷 한 상황 이 자주 발생 합 니 다.다른 사람 이 쓴 dll 라 이브 러 리 는 사용 하고 싶 지만 프로그램 문서 자료 가 없습니다.이때 C\#Runtime 이 제공 하 는 기능 을 통 해 이 dll 라 이브 러 리 를 프로그램 에 불 러 오고 dll 의 모든 내용 을 자세히 연구 할 수 있 습 니 다.이것 이 바로 C\#의 반사 입 니 다.
개인 적 으로 가장 두 드 러 진 장점 이나 존재 하 는 합 리 성 을 반사 한다 고 생각 합 니 다.프로그램 원본 코드 를 수정 하지 않 은 상태 에서 프로그램 기능 의 동적 조정(Runtime 동적 대상 생 성)을 실현 합 니 다.
예시:

 interface IRun {
  void Run();
 }
 class Person : IRun
 {
  public void Run()
  {
   Console.WriteLine(" , LOL !");
  }
 }
 class Car : IRun
 {
  public void Run()
  {
   Console.WriteLine(" ...........");
  }
 }
 class Program
 {
  static void Main(string[] args)
  {
   IRun e = new Person();
   e.Run();
   Console.ReadLine();
  }
 }
위의 Run 기능 을 반드시 Person 이 수행 하 는 것 이 아니라면,때로는 Car 가 필요 하고,때로는 Person 이 필요 하 다.흔히 볼 수 있 는 해결 방안 은 if 등 판단 구 조 를 추가 하 는 것 입 니 다.다음 과 같 습 니 다.

 static void Main(string[] args)
  {
   Console.WriteLine("   :Car Person");
   string type = Console.ReadLine();
   IRun e = null;
   if ("Car" == type)
   {
    e = new Car();
   }else if("Person" == type)
   {
    e = new Person();
   }
   if(null != e)
    e.Run();
   Console.ReadLine();
  }
이런 구 조 는 확실히 현재 의 수 요 를 해 결 했 지만 결코 건장 하지 않다.IRun 인터페이스 가 실현 되 고 관련 유형의 계승 이 증가 함 에 따라 위의 판단 구조 도 급속히 성장 할 것 이다.대상 을 대상 으로 프로 그래 밍,디자인 모델 이 모두 지 키 는 큰 원칙 은 패키지 변환 이기 때문에 위의 프로그램 은 변화 에 잘 대응 하지 못 한다.여기 서 우 리 는'디자인 모델 의'지식 과 관련 되 지 않 기 때문에 아래 의 예제 코드 는 위의 절 차 를 간소화 하기 위해 디자인 모델 에 관 한 지식 을 의도 적 으로 사용 하지 않 았 다.다음 과 같다.     

 static void Main(string[] args)
  {
   Console.WriteLine("   :Car Person");
   string type = Console.ReadLine();
   string classPath = String.Format("namespace.{0}", type);
   IRun e = Activator.CreateInstance(null, classPath).Unwrap() as IRun;

   if(null != e)
    e.Run();
   Console.ReadLine();
  }
위의 수정 을 통 해 프로그램 은 사용자 의 입력 에 따라 Activator.Create Instance 를 통 해 IRun 의 인 스 턴 스 를 만 들 수 있 습 니 다.프로그램 은 더 이상 IRun 의 실현 자가 증가 함 에 따라 이러한 문제 의 영향 을 받 지 않 습 니 다.위의 이런 장점 은 바로 반 사 를 통 해 얻 은 것 이자 내 가 생각 하 는'반사 존재의 합 리 성'이다.
Activator,Assembly 반사 방식 으로 대상 만 들 기
C\#에서 반사 방식 으로 대상 을 만 들 수 있 습 니 다.Activator.Create Instance(정적)와 Assembly.Create Instance(비 정적)를 통 해 이 루어 집 니 다.그 중에서 Assembly.Create Instance 내부 에서 호출 된 것 은 Activator.Create Instance 입 니 다.
동적 으로 만 들 형식 대상 이 현재 프로그램 집합 에 있 는 지 여부 에 따라 반사 생 성 대상 을 프로그램 집합 내의 유형 대상 과 프로그램 집합 밖의 유형 대상 으로 나 눌 수 있 습 니 다.
프로그램 집합 내 형식 대상 만 들 기

  private static void ReflectionIRun1(string className)
  {
   string classPath = String.Format("namespace.{0}", className);
   //   null ,                  
   var handler = Activator.CreateInstance(null, classPath);
   IRun e = (IRun)handler.Unwrap();
   Console.WriteLine(e.Run());
  }
  private static void ReflectionIRun2(string className)
  {
   string classPath = String.Format("namespace.{0}", className);
   //typeof(IRun).Assembly    IRun         
   object obj = typeof(IRun).Assembly.CreateInstance(null, classPath);
   IRun e = (IRun)obj;
   Console.WriteLine(e.Run());
  }
프로그램 집합 밖의 형식 대상 만 들 기
항목 에 라 이브 러 리(다른 프로그램 집합)를 추가 합 니 다.다음 그림:

Boss 클래스 를 추가 합 니 다.다음 과 같 습 니 다.

namespace Lib
{
 public class Boss
 {
  private string name = "  ";
  
  public string Name{
   get {return name;}
  }
  public string Talk()
  {
   return "       ......";
  }
  //      ,     ,          Payfor  private,        
  private int Payfor(int total)
  {
   return total + 10;
  }
 }
} 
Boss 대상 을 가 져 오기 전에 Lib 에 대한 인용 을 추가 하고 다음 과 같은 예 시 를 가 져 옵 니 다.

 private static void ReflectionBoss1()
  {
   string classPath ="Lib.Boss";
   //"Lib"            (                  )
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   Console.WriteLine(b.Talk());
  }
  private static void ReflectionBoss2()
  {
   string classPath ="Lib.Boss";
   //Assembly.Load("Lib")       (                  )
   var assembly = Assembly.Load("Lib");
   Boss b = (Boss)assembly.CreateInstance(classPath);
   Console.WriteLine(b.Talk());
  } 
반사 시 CLR 이 불 러 올 프로그램 집합 을 어떻게 찾 고 찾 는 지 에 대해 서 는 MSDN 에서 반사 에 관 한 지식 을 참고 하 시기 바 랍 니 다.
반사 접근 필드,호출 방법(속성)
반 사 는 대상 을 동적 으로 만 들 수 있 는 것 외 에 도 대상 을 동적 으로 방문 하 는 방법(속성)이나 필드 를 도 울 수 있 습 니 다.C\#버 전에 따라 구체 적 인 방법 이 변경 되 거나 확 장 될 수 있 으 므 로 더욱 깊이 있 는 내용 은 MSDN 을 참고 하 시기 바 랍 니 다.다음은 간단 한 예시 만 한다.
사장 의 이름 을 바꾸다.      

 private static void ReflectionBoss1()
  {
   string classPath = "Lib.Boss";
   //"Lib"            (                  )
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   //    
   FieldInfo f = b.GetType().GetField("name", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
   f.SetValue(b, "  ");
   Console.WriteLine("{0}:{1}", b.Name, b.Talk());
  }
출력:

사장 에 게 돈 을 지불 하 게 하 다.

private static void ReflectionBoss1()
  {
   string classPath = "Lib.Boss";
   //"Lib"            (                  )
   var handler = Activator.CreateInstance("Lib", classPath);
   Boss b = handler.Unwrap() as Boss;
   //    
   MethodInfo method = b.GetType().GetMethod("Payfor", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance);
   object money = method.Invoke(b, new object[] { 10 });
   Console.WriteLine("DW039:      10    ......");
   Console.WriteLine("{0}:.....,    ,     。",b.Name);
   Console.WriteLine("DW039:......");
   Console.WriteLine("{0}:{1}", b.Name,money);
   Console.WriteLine("DW039:     !");
  }
출력:

dynamic 와 반사 쌍 검 합 벽
반 사 는 실 행 될 때의 유형 조작 이기 때문에 프로 그래 밍 할 때 유형 이 불확실 한 문제 에 직면 합 니 다.이전'C\#익명 대상(익명 유형),var,동적 유형 다이나믹'에 따 르 면 다이나믹 동적 유형 은 우리 가 작성 한 반사 프로그램 과 결합 하여 프로그램 논 리 를 크게 최적화 할 수 있 습 니 다.
위 코드 최적화:

private static void ReflectionBoss1()
  {
   string classPath ="Lib.Boss";
   var handler = Activator.CreateInstance("Lib", classPath);
   dynamic b = handler.Unwrap();
   Console.WriteLine(b.Talk());
  }
  private static void ReflectionBoss2()
  {
   string classPath ="Lib.Boss";
   var assembly = Assembly.Load("Lib");
   dynamic b = assembly.CreateInstance(classPath);
   Console.WriteLine(b.Talk());
  } 
다이나믹 동적 유형 대상 b 를 통 해 반사 대상 의 속성,방법 을 직접 호출 하여 빈번 한 유형 변환 작업 을 줄 일 수 있 습 니 다.
반사 흔 한 응용 장면
응용 장면 에서 제 가 가장 기억 에 남 는 것 은 MS Petshop 예제 입 니 다.SQL Server 데이터 베이스 에서 Oacle 데이터 베이스 로 전환 할 때 서로 다른 데이터 액세스 층 을 반사 적 으로 얻 었 습 니 다.그러나 제 실제 프로젝트 에서 데이터 베 이 스 를 중간 에 전환 하 는 상황 을 만난 적 이 없고 다른 응용 장면 은 대체적으로 위의 사례 와 비슷 합 니 다.친구 가 더 많은 응용 장면 을 발견 하면 보충 해 주세요.3ks.
반사 적 장단 점
장점:반사 로 프로그램 유연성
단점:반사 운행 속도 가 상대 적 으로 느리다.
반사 가 일반 프로그램 보다 느 린 것 에 대해 서 는 테스트 를 해 본 적 이 없고 진행 할 생각 도 없다.현실 상황 은 Ms 가 dynamic,Mvc 유행,Ms 가 CLR 에 대한 최적화,기계 성능 의 향상 을 제창 하기 때문에 개발 과정 에서 반사 적 인 성능 문 제 를 지나치게 고려 할 필요 가 없다.만약 당신 이 쓴 프로그램의 운행 속도 에 병목 이 생 긴 다 면(먼저 자신의 프로그램 이 쓴 합 리 성 을 확보 해 야 한다)데이터베이스 최적화,데이터 캐 시,웹 캐 시,부하 균형 등 기술 을 연구 해 보 세 요.저 는 더욱 현실 적 이 라 고 생각 합 니 다.

좋은 웹페이지 즐겨찾기