C# 早期和晚期绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/484214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:12:41  来源:igfitidea点击:

Early and late binding

c#bindinglate-binding

提问by

I'm trying to get my head around when early/late binding occurs in C#.

当 C# 中发生早/晚绑定时,我正在努力解决问题。

Non-virtual methods are always early bound. Virtual methods are always late bound: the compiler inserts extra code to resolve the actual method to bind to at execution time and checks for type safety. So subtype polymorphism uses late binding.

非虚拟方法总是提前绑定。虚拟方法总是后期绑定:编译器插入额外的代码来解析在执行时绑定到的实际方法并检查类型安全。所以子类型多态使用后期绑定。

Calling methods using reflection is an example of late binding. We write the code to achieve this as opposed to the compiler. (E.g. calling COM components.)

使用反射调用方法是后期绑定的一个例子。我们编写代码来实现这一点,而不是编译器。(例如调用 COM 组件。)

VB.NET supports implicit late binding when Option Strict is off. An object is late bound when it is assigned to a variable declared to be of type Object. The VB compiler inserts code to bind to the right method at execution time and to catch invalid calls. C# does not support this feature.

当 Option Strict 关闭时,VB.NET 支持隐式后期绑定。当一个对象被分配给一个声明为 Object 类型的变量时,它就是后期绑定的。VB 编译器插入代码以在执行时绑定到正确的方法并捕获无效调用。C# 不支持此功能。

Am I heading in the right direction?

我是否朝着正确的方向前进?

What about calling delegates and calling a method through an interface reference? Is that early or late binding?

如何通过接口引用调用委托和调用方法?是早绑定还是晚绑定?

回答by Scott Langham

Everything is early bound in C# unless you go through the Reflection interface.

除非您通过反射接口,否则一切都在 C# 中早期绑定。

Early bound just means the target method is found at compile time, and code is created that will call this. Whether its virtual or not (meaning there's an extra step to find it at call time is irrelevant). If the method doesn't exist the compiler will fail to compile the code.

早期绑定仅意味着在编译时找到目标方法,并创建将调用此方法的代码。它是否是虚拟的(意味着在调用时需要一个额外的步骤来找到它是无关紧要的)。如果该方法不存在,编译器将无法编译代码。

Late bound means the target method is looked up at run time. Often the textual name of the method is used to look it up. If the method isn't there, bang. The program will crash or go into some exception handling scheme at run time.

后期绑定意味着在运行时查找目标方法。通常使用方法的文本名称来查找它。如果方法不存在,砰。程序将在运行时崩溃或进入某些异常处理方案。

Most script languages use late binding, and compiled languages use early binding.

大多数脚本语言使用后期绑定,编译语言使用早期绑定。

C# (prior to version 4) doesn't late bind; they can however use the reflection API to do it. That API compiles to code that looks up function names by digging through assemblies at run time. VB can late bind if Option Strict is turned off.

C#(版本 4 之前)不会延迟绑定;然而,他们可以使用反射 API 来做到这一点。该 API 编译为通过在运行时挖掘程序集来查找函数名称的代码。如果 Option Strict 关闭,VB 可以延迟绑定。

Binding usually has an effect on performance. Because late binding requires lookups at runtime, it is usually means method calls are slower than early bound method calls.

绑定通常会影响性能。因为后期绑定需要在运行时查找,这通常意味着方法调用比早期绑定方法调用慢。



For a normal function, the compiler can work out the numeric location of it in memory. Then it when the function is called it can generate an instruction to call the function at this address.

对于普通函数,编译器可以计算出它在内存中的数字位置。然后当函数被调用时,它可以生成一个指令来调用这个地址的函数。

For an object that has any virtual methods, the compiler will generate a v-table. This is essentially an array that contains the addresses of the virtual methods. Every object that has a virtual method will contain a hidden member generated by the compiler that is the address of the v-table. When a virtual function is called, the compiler will work out what the position is of the appropriate method in the v-table. It will then generate code to look in the objects v-table and call the virtual method at this position.

对于具有任何虚方法的对象,编译器将生成一个 v-table。这本质上是一个包含虚拟方法地址的数组。每个具有虚方法的对象都将包含一个由编译器生成的隐藏成员,即 v-table 的地址。当调用虚函数时,编译器会计算出合适方法在 v-table 中的位置。然后它将生成代码以查看对象 v-table 并在此位置调​​用虚拟方法。

So, there is a lookup that occurs for the virtual function. This is heavily optimized so it will happen very quickly at run-time.

因此,对虚函数进行了查找。这是经过大量优化的,因此它会在运行时很快发生。

Early bound

早期绑定

  • The compiler can work out where the called function will be at compile time.
  • The compiler can guarantee early (before any of the programs code runs) that the function will exist and be callable at runtime.
  • The compiler guarantees that the function takes the right number of arguments and that they are of the correct type. It also checks that the return value is of the correct type.
  • 编译器可以计算出被调用函数在编译时的位置。
  • 编译器可以尽早(在任何程序代码运行之前)保证该函数将存在并可在运行时调用。
  • 编译器保证函数采用正确数量的参数并且它们是正确的类型。它还检查返回值的类型是否正确。

Late-binding

后期绑定

  • The lookup will take longer because its not a simple offset calculation, there are usually text comparisons to be made.
  • The target function may not exist.
  • The target function may not accept the arguments passed to it, and may have a return value of the wrong type.
  • With some implementations, the target method can actually change at run-time. So, the lookup may execute a different function. I think this happens in the Ruby language, you can define a new method on an object while the program is running. Late-binding allows function calls to start calling a new override for a method instead of calling the existing base method.
  • 查找将花费更长的时间,因为它不是简单的偏移计算,通常需要进行文本比较。
  • 目标函数可能不存在。
  • 目标函数可能不接受传递给它的参数,并且可能具有错误类型的返回值。
  • 对于某些实现,目标方法实际上可以在运行时更改。因此,查找可能会执行不同的功能。我认为这发生在 Ruby 语言中,您可以在程序运行时在对象上定义一个新方法。后期绑定允许函数调用开始为方法调用新的覆盖,而不是调用现有的基方法。

回答by Joe Erickson

C# 3 uses early binding.

C# 3 使用早期绑定。

C# 4 adds late binding with the dynamickeyword. See Chris Burrow's blog entryon the subject for details.

C# 4 添加了带有dynamic关键字的后期绑定。有关详细信息,请参阅Chris Burrow关于该主题的博客条目

As for virtual versus non-virtual methods, this is a different issue. If I call string.ToString(), the C# code is bound to the virtual object.ToString()method. The code of the caller does not change based on the type of the object. Rather, virtual methods are called through a table of function pointers. An instance of object refers to object's table pointing at it's ToString()method. An instance of string has it's virtual method table pointing at it's ToString()method. Yes, this is polymorphism. but it is not late binding.

至于虚拟方法与非虚拟方法,这是一个不同的问题。如果我调用string.ToString(),C# 代码绑定到虚拟object.ToString()方法。调用者的代码不会根据对象的类型而改变。相反,虚拟方法是通过函数指针表调用的。对象的实例引用指向它的ToString()方法的对象表。字符串的实例具有指向它的ToString()方法的虚拟方法表。是的,这就是多态。但它不是后期绑定。

回答by csexpert

This article is a guide to building a .net component ,using it in a Vb6 project at runtime using late binding, attaching it's events and get a callback.

本文是构建 .net 组件的指南,在运行时使用后期绑定在 Vb6 项目中使用它,附加它的事件并获得回调。

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

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

This article is a guide to building a .NET component and using it in a VB6 project. There are many samples about this issue, so why did I write a new one? In my humble opinion, in other articles, the missing part is to attach its event at runtime. So in this article, we will build a .NET component, mark it as a COM visible component, use it at runtime in VB6 and attach to its events.

本文是构建 .NET 组件并在 VB6 项目中使用它的指南。关于这个问题的例子很多,我为什么要写一个新的?以我的拙见,在其他文章中,缺少的部分是在运行时附加其事件。因此,在本文中,我们将构建一个 .NET 组件,将其标记为 COM 可见组件,在 VB6 中在运行时使用它并附加到其事件。

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

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

Most developers often need Internet Explorer automation, which basically means opening a browser, filling some forms, and posting data programmatically.

大多数开发人员通常需要 Internet Explorer 自动化,这基本上意味着打开浏览器、填写一些表单并以编程方式发布数据。

The most common approach is to use shdocvw.dll (the Microsoft Web Browser control) and Mshtml.dll (the HTML Parsing and Rendering Component), or Microsoft.Mshtml.dll which is actually a .NET wrapper for Mshtml.dll. You can get more information about Internet Explorer - About the Browser here.

最常见的方法是使用 shdocvw.dll(Microsoft Web 浏览器控件)和 Mshtml.dll(HTML 解析和呈现组件),或 Microsoft.Mshtml.dll,它实际上是 Mshtml.dll 的 .NET 包装器。您可以在此处获取有关 Internet Explorer - 关于浏览器的更多信息。

If you pick the above method and DLLs, let's see some of the problems you may have to deal with:

如果您选择上述方法和 DLL,让我们看看您可能需要处理的一些问题:

You have to distribute these DLLs because your project would be dependent to these DLLs, and this is a serious problem if you cannot deploy them correctly. Simply do some Googling about shdocvw and mshtml.dll distributing problems, and you'll see what I'm talking about. You have to deploy an 8 MB Microsoft.mshtml.dll because this DLL is not part of the .NET framework. In this case, what we need to do is use a late binding technique. Writing our own wrappers for the above mentioned DLLs. And of course, we'll do this as it is more useful than using these DLLs. For instance, we won't need to check if the document download operation is complete because IEHelper will do this for us.

您必须分发这些 DLL,因为您的项目将依赖于这些 DLL,如果您不能正确部署它们,这将是一个严重的问题。只需对 shdocvw 和 mshtml.dll 分发问题进行一些 Google 搜索,您就会明白我在说什么。您必须部署 8 MB Microsoft.mshtml.dll,因为此 DLL 不是 .NET 框架的一部分。在这种情况下,我们需要做的是使用后期绑定技术。为上述 DLL 编写我们自己的包装器。当然,我们会这样做,因为它比使用这些 DLL 更有用。例如,我们不需要检查文档下载操作是否完成,因为 IEHelper 会为我们做这件事。

回答by Prasad

In most cases early binding is what we do on a daily basis. For example, if we have have an Employeeclass available at compile time, we simply create the instance of that class and invoke any instance members. This is early binding.

在大多数情况下,早期绑定是我们每天都会做的事情。例如,如果我们有一个Employee在编译时可用的类,我们只需创建该类的实例并调用任何实例成员。这是早期绑定。

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

On the other hand, if you don't have the knowledge of the class at compile time, then the only way is to late bind using reflection. I have come across an excellent video explaining these concepts -- here's the link.

另一方面,如果您在编译时不了解类,那么唯一的方法就是使用反射进行后期绑定。我遇到了一个解释这些概念的优秀视频——这是链接

回答by Suresh

In very simple terms, early binding happens at compile time and the compiler has the knowledge about the type and all it's members, and late binding happens at run time, the compiler doesn't know anything about the type and it's members. I have come across an excellent video on youtube which explains these concepts.

简单来说,早期绑定发生在编译时,编译器知道类型及其所有成员,后期绑定发生在运行时,编译器对类型及其成员一无所知。我在 youtube 上看到了一个很好的视频,它解释了这些概念。

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

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

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

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

回答by Kumar Nitesh

Its a very old post but wanted to add more info to it. Late binding is used when you dont want to instantiate object at compile time. In C#you use Activatorto call bind object at runtime.

它是一个非常旧的帖子,但想添加更多信息。当您不想在编译时实例化对象时使用后期绑定。在C#你用来Activator在运行时调用绑定对象。

回答by RajGanesh

Early Binding

早期绑定

The name itself describes that compiler knows about what kind of object it is, what are all the methods and properties it contains. As soon as you declared the object, .NET Intellisense will populate its methods and properties on click of the dot button.

名称本身描述了编译器知道它是什么类型的对象,它包含的所有方法和属性是什么。声明对象后,.NET Intellisense 将在单击点按钮时填充其方法和属性。

Common Examples:

常见示例:

ComboBox cboItems;

组合框 cboItems;

ListBox lstItems; In the above examples, if we type the cboItem and place a dot followed by, it will automatically populate all the methods, events and properties of a combo box, because compiler already know it's an combobox.

列表框 lstItems; 在上面的例子中,如果我们输入 cboItem 并在后面放一个点,它会自动填充组合框的所有方法、事件和属性,因为编译器已经知道它是一个组合框。

Late Binding

后期绑定

The name itself describes that compiler does not know what kind of object it is, what are all the methods and properties it contains. You have to declare it as an object, later you need get the type of the object, methods that are stored in it. Everything will be known at the run time.

名称本身说明编译器不知道它是什么类型的对象,它包含的所有方法和属性是什么。您必须将其声明为一个对象,稍后您需要获取该对象的类型以及存储在其中的方法。一切都会在运行时知道。

Common Examples:

常见示例:

Object objItems;

对象 objItems;

objItems = CreateObject("DLL or Assembly name"); Here during the compile time, type of objItems is not determined. We are creating an object of a dll and assigning it to the objItems, so everything is determined at the run time.

objItems = CreateObject("DLL 或程序集名称"); 这里在编译期间,objItems 的类型是不确定的。我们正在创建一个 dll 对象并将其分配给 objItems,因此一切都在运行时确定。

Early Binding vs. Late Binding

早期绑定与晚期绑定

Now coming into the picturea|

现在进入图片a|

Application will run faster in Early binding, since no boxing or unboxing are done here.

应用程序将在早期绑定中运行得更快,因为这里没有进行装箱或拆箱。

Easier to write the code in Early binding, since the intellisense will be automatically populated

在早期绑定中更容易编写代码,因为智能感知将自动填充

Minimal Errors in Early binding, since the syntax is checked during the compile time itself.

早期绑定中的最小错误,因为在编译时本身检查语法。

Late binding would support in all kind of versions, since everything is decided at the run time.

后期绑定将支持所有类型的版本,因为一切都是在运行时决定的。

Minimal Impact of code in future enhancements, if Late Binding is used.

如果使用后期绑定,代码在未来增强中的影响最小。

Performance will be code in early binding. Both have merits and demerits, it's the developer decision to choose the appropriate binding based on the scenario.

性能将是早期绑定的代码。两者都有优点和缺点,开发人员决定根据场景选择合适的绑定。