Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is possible to assign partial methods to delegates in spite of other constraints?

I know the title might not be totally clear, but I didn't want to make it too long.

One thing boggles me when thinking about restrictions placed on partial methods. It seems to me that the rules are inconsistent. As you probably know:

Partial methods must always have a return type of void, and they cannot have any parameters marked with the out modifier. These restrictions are in place because at run time, the method may not exist and so you can’t initialize a variable to what the method might return because the method might not exist. Similarly, you can’t have an out parameter because the method would have to initialize it and the method might not exist. [1]

It sounds sensible to me. But at the same time:

If there is no implementing partial method declaration, then you cannot have any code that attempts to create a delegate that refers to the partial method. Again, the reason is that the method doesn’t exist at run time. [1]

At first, all these rules seem to follow the same compiler logic. There is a difference, though. As stated in the second quotation, compiler issues an error only when there is no method implementation of the partial method. Why can't it also check for the implementation at compile-time in other scenarios? This would allow much more flexibility when using partial methods and the logic behind all rules would be identical.

I am afraid that the only answer I can get is "Because that's how it was implemented", but maybe there is something more to it?

[1] CLR via C#, Fourth Edition

like image 200
Kapol Avatar asked Jun 10 '15 18:06

Kapol


People also ask

What will happen if there is an implementation of partial method without defining partial?

Similar to a partial class, a partial method can be used as a definition in one part while another part can be the implementation. If there is no implementation of the partial method then the method and its calls are removed at compile time. Compiler compiles all parts of a partial method to a single method.

What is the use of partial methods?

A partial method has its signature defined in one part of a partial type, and its implementation defined in another part of the type. Partial methods enable class designers to provide method hooks, similar to event handlers, that developers may decide to implement or not.

What is a restriction for C# partial methods?

There are some rules and restrictions apply to the partial method. The signature of partial method must be same in both partial classes. The partial method must return void. No access modifiers are allowed.


1 Answers

The whole point of partial methods is to facilitate extensibility in generated code scenarios without runtime performance impact. The code generator emits a partial method signature, and then emits code that calls this partial method.

Now, at compile time, if the method isn't implemented, these call sites get entirely removed, and the remaining code has to be valid. The quotes are confusing in this regard, because they're talking about "runtime existence" of the method. That's nonsense: everything is resolved at compile time.

This is the reason for the difference: the rules you quoted first impose restrictions on the method signature, whereas the delegate rule imposes a restriction on method usage.

The rules about the signature make sure you can call the method in a manner the code will remain valid if the method call is removed. And the intended use case for partial methods is for them to be absent 99% of the time. If you require them to be implemented then that's not the feature you should be using in the first place. Use an abstract method or something alike.

Building a delegate to a method is like taking the pointer to the method, and you can't do that if the method doesn't exist (well, I suppose you could argue the compiler could just replace the delegate with null at this point, but you can't write, say, new Action(null)), yet there is no reason to disallow it if the method does exist, for the implementer's convenience. But the code generator shouldn't emit code that creates delegates to the method.

like image 181
Lucas Trzesniewski Avatar answered Nov 15 '22 00:11

Lucas Trzesniewski