C\#Dynamic 키워드 의:dynamic 왜 반사 보다 빠 른 지 에 대한 상세 한 설명

9471 단어 dynamic반사
주요 방법 은 다음 과 같다.
clip_image002
reflactor 역 컴 파일 을 사용 하면 다음 을 볼 수 있 습 니 다:
전체 코드 는 다음 과 같 습 니 다:

static void Main(string[] args)
{
    dynamic str = "abcd";
    Console.WriteLine(str.Length);

    Console.WriteLine();
    Console.WriteLine(str.Substring(1));


    Console.ReadLine();
}

먼저 컴 파일 러 는 정적 클래스 를 자동 으로 생 성 합 니 다.다음 과 같 습 니 다

private static void Main(string[] args)
{
      object obj1 = "abcd";
      if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
      {
            Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, Type, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "WriteLine", null, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
      }
      if (Program.<Main>o__SiteContainer0.<>p__Site2 == null)
      {
            Program.<Main>o__SiteContainer0.<>p__Site2 = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, "Length", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
      }
      Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, typeof(Console), Program.<Main>o__SiteContainer0.<>p__Site2.Target(Program.<Main>o__SiteContainer0.<>p__Site2, obj1));
      Console.WriteLine();
      if (Program.<Main>o__SiteContainer0.<>p__Site3 == null)
      {
            Program.<Main>o__SiteContainer0.<>p__Site3 = CallSite<Action<CallSite, Type, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "WriteLine", null, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
      }
      if (Program.<Main>o__SiteContainer0.<>p__Site4 == null)
      {
            Program.<Main>o__SiteContainer0.<>p__Site4 = CallSite<Func<CallSite, object, int, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.None, "Substring", null, typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }));
      }
      Program.<Main>o__SiteContainer0.<>p__Site3.Target(Program.<Main>o__SiteContainer0.<>p__Site3, typeof(Console), Program.<Main>o__SiteContainer0.<>p__Site4.Target(Program.<Main>o__SiteContainer0.<>p__Site4, obj1, 1));
      Console.ReadLine();
}
왜 여기에 네 개의 CallSite대상 이 있 습 니까?저희 코드 에 있어 요.
Console.WriteLine(str.Length);Console.WriteLine();Console.WriteLine(str.Substring(1));모두 네 차례 다이나믹 대상 을 사용 했다.1:Console.WriteLine(dynamic); str.Length 는 dynamic 2:dynamic.Length 를 되 돌려 줍 니 다.3:Console.WriteLine(dynamic); str.Substring 은 dynamic 4:dynamic.Substring(1)을 되 돌려 줍 니 다.1,2,3,4,각각 위의<>p 에 대응Site1,2,3,4;
1,3 은 모두 반환 값 이 없 기 때문에 Action 입 니 다.2,4 는 모두 반환 값 이 있 기 때문에 Func 입 니 다.위의 코드 를 보면 아직 잘 모 르 겠 지만 수 동 으로 코드 를 생 성 합 시다.컴 파일 러 가 자동 으로 생 성 하 는 클래스 대신 새 클래스 SiteContainer 입 니 다

[CompilerGenerated]
private static class <Main>o__SiteContainer0
{
      // Fields
      public static CallSite<Action<CallSite, Type, object>> <>p__Site1;
      public static CallSite<Func<CallSite, object, object>> <>p__Site2;
      public static CallSite<Action<CallSite, Type, object>> <>p__Site3;
      public static CallSite<Func<CallSite, object, int, object>> <>p__Site4;
}
이어서 초기 화 pSite 1 시 방법:

[CompilerGenerated]
public static class SiteContainer
{
  // Fields
  public static CallSite<Action<CallSite, Type, object>> p__Site1;
  public static CallSite<Func<CallSite, object, object>> p__Site2;
  public static CallSite<Action<CallSite, Type, object>> p__Site3;
  public static CallSite<Func<CallSite, object, int, object>> p__Site4;
}
InvokeMember 방법의 서명:Public static CallSiteBinder InvokeMember(CSharpBinderFlags flags,string name,IEnumerabletypeArguments,Type context,IEnumerableargument Info);1:여기 서 CSharp BinderFlags 는 ResultDiscarded 를 전달 합 니 다.결 과 는 버 려 졌 습 니 다.   그래서 void 의 반환 방법 에 연결 할 수 있 습 니 다.2:name 은"Write Line"을 전달 합 니 다.호출 할 방법의 이름 입 니 다.3:type:arguments.형식 매개 변수의 목록,null 전달.4:context:이 작업 의 사용 위 치 를 표시 하 는 System.Type 입 니 다.여 기 는 Program 5:argument Info:매개 변수 정보 입 니 다.   이어서 pSite 2 어떻게 초기 화 했 나 요?
.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

if (SiteContainer.p__Site1 == null)
{
    CallSiteBinder csb= Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(
        CSharpBinderFlags.ResultDiscarded,
        "WriteLine", null, typeof(Program),
        new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType,null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,null)
        });
    SiteContainer.p__Site1 = CallSite<Action<CallSite, Type, object>>.Create(csb);
}

if (SiteContainer.p__Site2 == null)
{
    CallSiteBinder csb = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(
        CSharpBinderFlags.None, "Length", typeof(Program),
        new CSharpArgumentInfo[]
        {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
        });

    SiteContainer.p__Site2 = CallSite<Func<CallSite, object, object>>.Create(csb);
}

    , p__Site1    ,    GetMember  。
 
      CallSite<T>   ,            ??
  CallSite<T>.Target       。
 
image 
Substring 방법 에 대응 하 는 것 은 pSite 4,Substring 방법 이 매개 변수 1 을 전달 하고 반환 값 이 있 기 때문에
p__Site 4 대상 은:
public static CallSite> p__Site4;초기 화:
 
기본 과 위의 pSite 1 과 유사 합 니 다.다만 매개 변수 정 보 는:CSharpArgument InfoFlags.Constant\\입 니 다.
Substring(1)을 호출 했 기 때 문 입 니 다.컴 파일 할 때 1 을 전달 하고 1 은 상수 입 니 다.호출 은 다음 과 같다.
완전한 Main 함수 코드 는 다음 과 같 습 니 다
//          ://SiteContainer.p__Site1.Target(SiteContainer.p__Site1, typeof(Console), // SiteContainer.p__Site2.Target(SiteContainer.p__Site2, obj1) //); var pSite2Result = SiteContainer.p__Site2.Target(SiteContainer.p__Site2, obj1); SiteContainer.p__Site1.Target(SiteContainer.p__Site1, typeof(Console), pSite2Result);
여기 서 저 는 p 를 사용 하지 않 았 습 니 다.Site 3,p 때문에Site 3 와 pSite 1 은 같 지만 왜 마이크로소프트 가 4 개의 CallSite대상 을 생 성 합 니까?1 과 3 이 똑 같 기 때문에 간단 함 을 실현 하기 위해 서 입 니까?초기 화 지연 이 있어 서 다행 입 니 다.그렇지 않 으 면 정적 필드 가 이렇게 많아 서 시스템 에 어떤 영향 을 미 칠 지 모 르 겠 습 니 다.결 과 는 다음 과 같 습 니 다.  clip_image002[4]
 
        :
  SiteContainer.p__Site2,   Length  
    p__Site2 target  ,  p__Site2,   obj1.

좋은 웹페이지 즐겨찾기