초기 및 후기 바인딩


83

C #에서 초기 / 늦은 바인딩이 발생할 때 머리를 돌리려고합니다.

비가 상 방법은 항상 초기에 바인딩됩니다. 가상 메서드는 항상 늦게 바인딩됩니다. 컴파일러는 실행시 바인딩 할 실제 메서드를 확인하기 위해 추가 코드를 삽입하고 형식 안전성을 확인합니다. 따라서 하위 유형 다형성은 후기 바인딩을 사용합니다.

리플렉션을 사용한 메서드 호출은 후기 바인딩의 예입니다. 컴파일러가 아니라이를 달성하기 위해 코드를 작성합니다. (예 : COM 구성 요소 호출)

VB.NET은 Option Strict가 꺼져있을 때 암시 적 후기 바인딩을 지원합니다. 객체는 Object 유형으로 선언 된 변수에 할당 될 때 후기 바인딩됩니다. VB 컴파일러는 실행 시간에 올바른 메서드에 바인딩하고 잘못된 호출을 포착하는 코드를 삽입합니다. C #은이 기능을 지원하지 않습니다.

올바른 방향으로 가고 있습니까?

대리자를 호출하고 인터페이스 참조를 통해 메서드를 호출하는 것은 어떻습니까? 그게 일찍 또는 늦게 구속됩니까?

답변:


103

Reflection 인터페이스를 거치지 않는 한 모든 것이 C #에서 조기 바인딩됩니다.

얼리 바운드는 컴파일 타임에 타겟 메소드가 발견되고이를 호출하는 코드가 생성된다는 것을 의미합니다. 가상 여부 (통화 시간에 찾을 수있는 추가 단계가 있음을 의미 함) 여부. 메서드가 없으면 컴파일러는 코드를 컴파일하지 못합니다.

Late bound는 대상 메서드가 런타임에 조회됨을 의미합니다. 종종 메서드의 텍스트 이름을 사용하여 검색합니다. 방법이 없으면 쾅. 프로그램은 런타임에 충돌하거나 일부 예외 처리 체계로 이동합니다.

대부분의 스크립트 언어는 후기 바인딩을 사용하고 컴파일 된 언어는 초기 바인딩을 사용합니다.

C # (버전 4 이전)은 늦게 바인딩하지 않습니다. 그러나 리플렉션 API를 사용하여 수행 할 수 있습니다. 이 API는 런타임에 어셈블리를 파헤쳐 함수 이름을 찾는 코드로 컴파일됩니다. Option Strict가 해제 된 경우 VB는 지연 바인딩 할 수 있습니다.

바인딩은 일반적으로 성능에 영향을 미칩니다. 후기 바인딩에는 런타임에 조회가 필요하기 때문에 일반적으로 메서드 호출이 초기 바인딩 된 메서드 호출보다 느리다는 것을 의미합니다.


일반 함수의 경우 컴파일러는 메모리에서 숫자 위치를 계산할 수 있습니다. 그런 다음 함수가 호출 될 때이 주소에서 함수를 호출하는 명령을 생성 할 수 있습니다.

가상 메서드가있는 개체의 경우 컴파일러는 v 테이블을 생성합니다. 이것은 본질적으로 가상 메소드의 주소를 포함하는 어레이입니다. 가상 메서드가있는 모든 개체에는 v 테이블의 주소 인 컴파일러에 의해 생성 된 숨겨진 멤버가 포함됩니다. 가상 함수가 호출되면 컴파일러는 v 테이블에서 적절한 메서드의 위치가 무엇인지 알아냅니다. 그런 다음 객체 v-table을 살펴보고이 위치에서 가상 메서드를 호출하는 코드를 생성합니다.

따라서 가상 기능에 대해 발생하는 조회가 있습니다. 이것은 매우 최적화되어 있으므로 런타임에 매우 빠르게 발생합니다.

조기 바인딩

  • 컴파일러는 컴파일 타임에 호출 된 함수가 어디에 있는지 알아낼 수 있습니다.
  • 컴파일러는 함수가 존재하고 런타임에 호출 가능하다는 것을 조기에 (프로그램 코드가 실행되기 전에) 보장 할 수 있습니다.
  • 컴파일러는 함수가 올바른 수의 인수를 취하고 올바른 유형인지를 보장합니다. 또한 반환 값이 올바른 유형인지 확인합니다.

늦은 바인딩

  • 단순한 오프셋 계산이 아니기 때문에 조회 시간이 더 오래 걸리며 일반적으로 텍스트 비교가 필요합니다.
  • 대상 기능이 없을 수 있습니다.
  • 대상 함수는 전달 된 인수를 받아들이지 않을 수 있으며 잘못된 유형의 반환 값을 가질 수 있습니다.
  • 일부 구현에서는 대상 메서드가 실제로 런타임에 변경 될 수 있습니다. 따라서 조회는 다른 기능을 실행할 수 있습니다. 이것은 Ruby 언어에서 발생한다고 생각합니다. 프로그램이 실행되는 동안 객체에 새로운 메소드를 정의 할 수 있습니다. 지연 바인딩을 사용하면 함수 호출이 기존 기본 메서드를 호출하는 대신 메서드에 대한 새 재정의 호출을 시작할 수 있습니다.

"VB 언어 자체는 늦게 바인딩되지 않습니다 ..."라고 말하려고하신 것 같습니다.
Michael Meadows

사실 저는 VB를 사용하지 않습니다. 그래서 그것에 대해 많이 알지 못합니다. 나는 C #을 의미했지만, 내 자신을 반복하는 것처럼 보입니다. 당신이 맞다고 생각할 것 같으니 고칠 게요!
Scott Langham

21
동적 타이핑은 후기 바인딩과 다릅니다. 차이는 미묘하지만 중요합니다. 후기 바인딩은 여전히 ​​유형에 바인딩되며 런타임에 수행됩니다. 동적 타이핑은 바인딩되지 않습니다. 대신 유형에 관계없이 런타임에 멤버 정보를 확인합니다.
Michael Meadows

1
" 가상 메소드가있는 객체의 경우 컴파일러는 v 테이블을 생성합니다. ". 이것은 "객체"가 아니라 "클래스"로 약간 잘못되었습니다.
turdus-merula

1
@IvanRuski 나는 그렇게 생각하지 않는다. 컴파일 타임에는 대리자가 허용하는 모든 인수 형식이 알려져 있습니다. 따라서 런타임 ( '늦음')이 아닌 컴파일 타임 ( '초기')에 컴파일러는 호출이 작동하도록 보장 할 수 있습니다.
Scott Langham

18

C # 3은 초기 바인딩을 사용합니다.

C # 4는 dynamic키워드를 사용하여 후기 바인딩을 추가 합니다. 자세한 내용 은 주제에 대한 Chris Burrow의 블로그 항목 을 참조하십시오.

가상 방법과 비가 상 방법의 경우 이것은 다른 문제입니다. 을 호출 string.ToString()하면 C # 코드가 가상 object.ToString()메서드에 바인딩됩니다 . 호출자의 코드는 개체 유형에 따라 변경되지 않습니다. 오히려 가상 메서드는 함수 포인터 테이블을 통해 호출됩니다. 개체의 인스턴스는 개체의 ToString()메서드를 가리키는 개체의 테이블을 참조합니다 . 문자열의 인스턴스에는 해당 메서드를 가리키는 가상 메서드 테이블이 ToString()있습니다. 예, 이것은 다형성입니다. 그러나 그것은 늦은 구속력이 아닙니다.


1
나는이 설명에 완전히 동의하지 않는다. C #에서 인스턴스 메서드 또는 필드를 가상으로 표시하면 파생 유형이 상속 체인의 기본 유형 구현을 재정의 할 수 있습니다. 가상 메서드를 사용하면 CLR은 런타임 개체 인스턴스를 기반으로 런타임에 호출 할 메서드를 알고 있습니다. 아마도 내가 동의하는 유일한 부분은 다형성의 구현 일 것입니다. 그렇다면 당신은 그것이 늦은 구속력이 아니라고 말함으로써 혼란을 야기합니다. CLR은 개체 인스턴스의 런타임 형식을 알고있는 경우에만 올바른 런타임 형식 구현을 호출 할 수 있으므로 늦은 바인딩입니다.
Julius Depulla

6

대부분의 경우 조기 바인딩은 우리가 매일하는 일입니다. 예를 들어, Employee컴파일 타임에 사용할 수 있는 클래스 가있는 경우 해당 클래스의 인스턴스를 만들고 인스턴스 멤버를 호출하기 만하면됩니다. 이것은 초기 바인딩입니다.

//Early Binding
**Employee** employeeObject = new **Employee**();
employeeObject.CalculateSalary();

반면에 컴파일 타임에 클래스에 대한 지식이 없다면 리플렉션을 사용하여 늦게 바인딩하는 것이 유일한 방법입니다. 저는 이러한 개념을 설명하는 훌륭한 비디오를 보았습니다 . 여기 링크가 있습니다.


3

매우 오래된 게시물이지만 더 많은 정보를 추가하고 싶었습니다. 레이트 바인딩은 컴파일 타임에 개체를 인스턴스화하고 싶지 않을 때 사용됩니다. 에서 C#당신이 사용하는 Activator런타임에 바인딩 개체를 호출 할 수 있습니다.


3

초기 바인딩

이름 자체는 컴파일러가 어떤 종류의 객체인지, 포함 된 모든 메서드와 속성에 대해 알고 있음을 설명합니다. 개체를 선언하자마자 .NET Intellisense는 점 버튼을 클릭하면 해당 메서드와 속성을 채 웁니다.

일반적인 예 :

ComboBox cboItems;

ListBox lstItems; 위의 예에서 cboItem을 입력하고 그 뒤에 점을 배치하면 컴파일러가 이미 콤보 상자임을 알고 있기 때문에 콤보 상자의 모든 메서드, 이벤트 및 속성이 자동으로 채워집니다.

늦은 바인딩

이름 자체는 컴파일러가 어떤 종류의 객체인지, 포함 된 모든 메서드와 속성을 알지 못한다고 설명합니다. 객체로 선언해야하며 나중에 객체의 유형, 저장된 메소드를 가져와야합니다. 모든 것은 런타임에 알려집니다.

일반적인 예 :

개체 objItems;

objItems = CreateObject ( "DLL 또는 어셈블리 이름"); 여기서 컴파일 시간 동안 objItems 유형은 결정되지 않습니다. 우리는 dll의 객체를 생성하고 objItems에 할당하고 있으므로 모든 것이 런타임에 결정됩니다.

초기 바인딩 vs. 후기 바인딩

이제 그림 속으로 ...

여기서는 boxing 또는 unboxing이 수행되지 않으므로 응용 프로그램이 Early binding에서 더 빠르게 실행됩니다.

인텔리 센스가 자동으로 채워 지므로 조기 바인딩에서 코드 작성이 더 쉽습니다.

컴파일 시간 자체에서 구문을 확인하므로 초기 바인딩의 최소 오류.

모든 것이 런타임에 결정되기 때문에 후기 바인딩은 모든 종류의 버전에서 지원됩니다.

후기 바인딩이 사용되는 경우 향후 개선 사항에서 코드의 영향을 최소화합니다.

성능은 초기 바인딩의 코드입니다. 둘 다 장점과 단점이 있으며 시나리오에 따라 적절한 바인딩을 선택하는 것은 개발자의 결정입니다.


2

매우 간단하게 말하면, 초기 바인딩은 컴파일 타임에 발생하고 컴파일러는 유형과 모든 멤버에 대한 지식을 가지고 있으며 런타임에 늦은 바인딩이 발생하며 컴파일러는 유형과 멤버에 대해 아무것도 알지 못합니다. 나는 이러한 개념을 설명하는 유튜브에서 훌륭한 비디오를 보았습니다.

http://www.youtube.com/watch?v=s0eIgl5iqqQ&list=PLAC325451207E3105&index=55&feature=plpp_video

http://www.youtube.com/playlist?list=PLAC325451207E3105


1

이 기사는 런타임에 Vb6 프로젝트에서 늦게 바인딩을 사용하여 이벤트를 연결하고 콜백을 가져 오는 .net 구성 요소를 빌드하는 방법에 대한 가이드입니다.

http://www.codeproject.com/KB/cs/csapivb6callback2.aspx

이 문서는 .NET 구성 요소를 빌드하고 VB6 프로젝트에서 사용하는 방법에 대한 가이드입니다. 이 문제에 대한 샘플이 많이 있는데 왜 새로 작성 했나요? 내 겸손한 의견으로는 다른 기사에서 누락 된 부분은 런타임에 이벤트를 첨부하는 것입니다. 따라서이 기사에서는 .NET 구성 요소를 빌드하고 COM 표시 구성 요소로 표시하고 VB6에서 런타임에 사용하고 이벤트에 연결합니다.

https://www.codeproject.com/Articles/37127/Internet-Explorer-Late-Binding-Automation

대부분의 개발자는 종종 Internet Explorer 자동화가 필요합니다. 이는 기본적으로 브라우저를 열고 일부 양식을 채우고 프로그래밍 방식으로 데이터를 게시하는 것을 의미합니다.

가장 일반적인 방법은 shdocvw.dll (Microsoft 웹 브라우저 컨트롤)과 Mshtml.dll (HTML Parsing and Rendering Component) 또는 실제로 Mshtml.dll의 .NET 래퍼 인 Microsoft.Mshtml.dll을 사용하는 것입니다. 여기에서 Internet Explorer-브라우저 정보에 대한 자세한 정보를 얻을 수 있습니다.

위의 방법과 DLL을 선택했다면 처리해야 할 몇 가지 문제를 살펴 보겠습니다.

프로젝트가 이러한 DLL에 종속되므로 이러한 DLL을 배포해야하며 올바르게 배포 할 수없는 경우 심각한 문제입니다. shdocvw 및 mshtml.dll 배포 문제에 대해 인터넷 검색을 수행하면 내가 무슨 말을하는지 알 수 있습니다. 이 DLL은 .NET 프레임 워크의 일부가 아니므로 8MB의 Microsoft.mshtml.dll을 배포해야합니다. 이 경우 우리가해야 할 일은 후기 바인딩 기술을 사용하는 것입니다. 위에서 언급 한 DLL에 대한 자체 래퍼를 작성합니다. 물론 이러한 DLL을 사용하는 것보다 더 유용하므로이 작업을 수행 할 것입니다. 예를 들어 문서 다운로드 작업이 완료되었는지 확인할 필요가 없습니다. IEHelper가이를 자동으로 수행하기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.