Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
278 views
in Technique[技术] by (71.8m points)

c# - Compiler generated sealed class for delegate keyword contains virtual methods

When delegate keyword is used in C#, the C# compiler automatically generates a class derived from System.MulticastDelegate class.

This compiler generated class contains 3 methods as well: Invoke, BeginInvoke and EndInvoke.

All these three methods are marked public virtual extern but interestingly the class itself is marked sealed.

Virtual methods defined in a sealed class not only strikes as counter-intuitive but are actually illegal in C#.

So my question is, is there a specific reason for this or is it just one of those harmless things done keeping in mind some hypothetical future enhancement?

Edit 1:

Can the reason be to force use of 'callVirt' IL opcode as opposed to 'call' so that delegate object is always checked for null by the CLR before trying to execute any of the three methods? Though I fail to see why a delegate should be a special case in this respect.

Also isn't it a performance hit to force use of callvirt (though it may be minuscule)

Edit 2:

Added CIL tag, as it turns out that the C# way of defining delegates is in fact mandated by the CIL standard. Standard states that (following is not full text)

Delegates shall have a base type of System.Delegate. Delegates shall be declared sealed, and the only members a delegate shall have are either the first two or all four methods as specified here. These methods shall be declared runtime and managed. They shall not have a body, since that body shall be created automatically by the VES. Other methods available on delegates are inherited from the class System.Delegate in the Base Class Library. The delegate methods are:

  1. The instance constructor
  2. The Invoke method shall be virtual
  3. The BeginInvoke method, if present, shall be virtual
  4. The EndInvoke method shall be virtual

So this is definitely not a side effect of compiler process or is similar to other interesting compiler outputs.

If standard emphasizes something, it must be for some good reason and rationale.

So the question now is why does CIL standard for delegates emphasizes on sealed and virtual at the same time?

Does the catch lie here?:

They shall not have a body, since that body shall be created automatically by the VES.

Are they marked virtual so that the VES/CLR generated body can be executed on invocation of these methods?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are being tripped up by the disassembler you used to look at the type definition. Which must translate the IL back to a recognizable language, like C#. This is not in general possible to do with full fidelity, the rules for IL are not the same as the C# language rules. This doesn't just happen for delegates, an interface implementation method is virtual as well, even though you don't declare it virtual in your C# code.

To further muddy the waters, IL actually permits a compiler to emit a non-virtual call for a virtual method if it can determine the target object from code analysis. But that will never happen for a delegate or interface call. And IL permits making a virtual call to a non-virtual method, something the C# compiler does with gusto to implement the guarantee that an instance method can never be called with a null this.

But that C# usage is a clever trick, discovered only after the CLR was designed. The original intent of virtual certainly was to annotate that the method should be called with Callvirt. Ultimately it doesn't matter because the compiler is aware of delegate and interface behavior and will always emit Callvirt. And the actual method call is implemented in CLR code which assumes a Callvirt activation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...