While inspecting delegates in C# and .NET in general, I noticed some interesting facts:
Creating a delegate in C# creates a class derived from MulticastDelegate with a constructor:
.method public hidebysig specialname rtspecialname instance
void .ctor(object 'object', native int 'method') runtime managed { }
Meaning that it expects the instance and a pointer to the method. Yet the syntax of constructing a delegate in C# suggests that it has a constructor
new MyDelegate(int () target)
where I can recognise int () as a function instance (int *target() would be a function pointer in C++). So obviously the C# compiler picks out the correct method from the method group defined by the function name and constructs the delegate. So the first question would be, where does the C# compiler (or Visual Studio, to be precise) pick this constructor signature from ? I did not notice any special attributes or something that would make a distinction. Is this some sort of compiler/visualstudio magic ? If not, is the T (args) target construction valid in C# ? I did not manage to get anything with it to compile, e.g.:
int () target = MyMethod;
is invalid, so is doing anything with MyMetod, e.g. calling .ToString() on it (well this does make some sense, since that is technically a method group, but I imagine it should be possible to explicitly pick out a method by casting, e.g. (int())MyFunction. So is all of this purely compiler magic ? Looking at the construction through reflector reveals yet another syntax:
Func CS$1$0000 = new Func(null, (IntPtr) Foo);
This is consistent with the disassembled constructor signature, yet this does not compile!
One final interesting note is that the classes Delegate and MulticastDelegate have yet another sets of constructors:
.method family hidebysig specialname rtspecialname instance
void .ctor(class System.Type target, string 'method') cil managed
Where does the transition from an instance and method pointer to a type and a string method name occur ? Can this be explained by the runtime managed keywords in the custom delegate constructor signature, i.e. does the runtime do it's job here ?
EDIT: ok, so I guess I should reformulate what I wanted to say by this question. Basically I'm suggesting that there's not only C# compiler / CLR magic involved in delegate construction, but also some Visual Studio magic, since Intellisense flips out some new syntax when suggesting the constructor arguments and even hides one of them (e.g. Reflector does not use this syntax and construtor, for that matter).
I was wondering whether this assertion is true, and whether the function instance syntax has some deeper meaning in C# or is it just some constant format implemented by the Visual Studio magic part for clarity (which makes sense, since it looks like invalid C#) ? In short, if I was implementing Intellisense, should I do some magic for delegates or could I construct the suggestion by some clever mechanism ?
FINAL EDIT: so, the popular consensus is that that's indeed VS magic. Seeing other examples (see Marc Gravell's comment) of such VS behavior convinces me that that is the case.
The first argument is resolved from the object reference (or null for static methods); no magic there.
Re the second argument, however - it is an unmanaged pointer (native int); in short, there is no alternative direct C# syntax that can use this constructor - it uses a specific IL instruction (ldftn) to resolve the function from metadata. However, you can use Delegate.CreateDelegate to create delegates via reflection. You can also use IL emit (DynamicMethod etc), but it isn't fun.
You first define the delegate (this is how Visual Studio knows the signature of the target method):
delegate void MyDelegate();
Then you construct delegate instances like this:
MyDelegate method = new MyDelegate({method name});
// If this was the method you wanted to invoke:
void MethodToInvoke()
{
// do something
}
MyDelegate method = new MyDelegate(MethodToInvoke);
C# automatically picks the method matching the signature of the delegate.
Edit: When Visual Studio's Intellisense shows you the int () target suggestion, it is showing you the signature of C# methods you can use. The C# compiler translates the C# representation to IL. The IL implementation will look different, because IL is not a C style language, and the C# compiler provides syntactic sugar to abstract away the implementation details.
This is just a guess, so don't shoot me if I'm wrong, but I think Intellisense is getting the signature for the target method from the Invoke method defined on the delegate. Reflector clearly shows that the Invoke method on System.Action<T> is:
[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]
public virtual void Invoke(T obj);
Which is the same as the signature suggestion offered by Intellisense. The magic is Intellisense, when spotting a delegate type, looks at the Invoke method and suggests a constructor that takes a target that matches it.
Related
I have implemented a compiler and virtual machine for a language. The implementation is in C# and the stack-based VM uses reflection to make function calls on a set of built-ins.
Much of the code involves simply pushing and popping stack values, but the workhorse is the function call. Currently the implementation of a function call looks like this:
var calli = gencode[pc++] as CallInfo;
var calla = PopStackList(calli.NumArgs).ToArray();
var ret = calli.MethodInfo.Invoke(instance, calla);
if (ret != null) PushStack(ret);
All data items passed and returned are objects using a custom type system (no native types used). Clarification: this is an instance method, not static.
Performance testing suggests that this MethodInfo.Invoke is quite slow. The question is how to make function calls at the highest possible speed, presumably by doing more preparatory work in the compiler and generating better code.
In response to suggestions, one possibility is to create a delegate. Unfortunately as far as I can tell a delegate has to be bound to a specific instance of a class, or to a static method, and creating a delegate after creating the instance rather defeats the purpose.
I see a vote to close, but to my eye the question is not broad at all. How should a compiler implement functions calls on instance methods in a virtual machine for best performance, at the very least faster than MethodInfo.Invoke()?
Well, if you’re sure your main problem is MethodInfo.Invoke…
Use stuff from System.Linq.Expressions (Expression.Call, Expression.Parameter) to create an expression that calls that MethodInfo method, passing your parameters for instance + arguments.
Compile that expression into Action<tInstance, tArgs[]> (don't know your types of these).
Cache that Action in your CallInfo class instance.
Invoke that action as needed.
How to convert MethodInfo.Invoke to delegate:
Normally when you’re calling methods with reflection, you call MethodInfo.Invoke. Unfortunately, this proves to be quite slow. If you know the signature of the method at compile-time, you can convert the method into a delegate with that signature using Delegate.CreateDelegate(Type, object, MethodInfo). You simply pass in the delegate type you want to create an instance of, the target of the call (i.e. what the method will be called on), and the method you want to call. It would be nice if there were a generic version of this call to avoid casting the result, but never mind. Here’s a complete example demonstrating how it works:
using System;
using System.Reflection;
public class Test
{
static void Main()
{
MethodInfo method = (string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
Func<char, int> converted = (Func<char, int>)
Delegate.CreateDelegate(typeof(Func<char, int>), “Hello”, method);
Console.WriteLine(converted(‘l’));
Console.WriteLine(converted(‘o’));
Console.WriteLine(converted(‘x’));
}
}
This prints out 2, 4, and -1; exactly what we’d get if we’d called "Hello".IndexOf(...) directly. Now let’s see what the speed differences are…
We’re mostly interested in the time taken to go from the main calling code to the method being called, whether that’s with a direct method call, MethodInfo.Invoke or the delegate. To make IndexOf itself take as little time as possible, I tested it by passing in ‘H’ so it would return 0 immediately. As normal, the test was rough and ready, but here are the results:
Invocation type Stopwatch ticks per invocation
Direct 0.18
Reflection 120
Delegate 0.20
Copied from: https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/
In C# I can do this:
delegate void myFunctionDelegate<T>(T arg);
In C++, I understand that I need to use an alias to a template for a function pointer, but the syntax is so bizaare that all of the examples I find just confuse me more.
The following is wrong; how can I correct it?
template<typename T>
using myFunctionDelegate = void (*)(T arg);
I want to use it like so:
template<class T> class Foo
{
...
void someOtherFunction(myFunctionDelegate callback)
{
...
callback(someValue);
}
}
and then:
myClassInstance.someOtherFunction([&](T arg) {
// do something with the callback argument
});
What you have almost works syntactically; the use of myFunctionDelegate simply needs a type argument:
void someOtherFunction(myFunctionDelegate<T> callback)
^^^
And the alias parameter names are optional if you aren't getting any particular benefit from them:
template<typename T>
using myFunctionDelegate = void(*)(T);
However, there is a larger problem: function pointers don't handle state. The lambda used in your sample call uses state by the capturing it does. Thus, a capturing lambda cannot be converted to a function pointer. When it's so handy to pass in such a lambda, function arguments should support that.
There are two common ways of doing so. The first is to forget about forcing a specific return and parameter type. Instead, let the caller pass any object (lambda, function pointer, functor, the result of std::bind) that can be called the way your function calls it:
template<typename Callable>
void someOtherFunction(Callable callback) {
...
callback(someValue);
}
If the call doesn't work, the code will fail to compile1 (with an error that unfortunately isn't too helpful, but the future Concepts additions can easily help there).
On the other hand, you might want to explicitly specify the function type. C++ has a general-purpose type to store any callable object (see the above list). That type is std::function. It's a bit more heavyweight than a simple template parameter, but useful when you need it.
template<typename T>
using myFunctionDelegate = std::function<void(T)>;
void someOtherFunction(const myFunctionDelegate<T> &callback) {...}
[1]: This isn't always true (see SFINAE), but it probably will be as far as you're concerned.
std::function<void(T)> myFunctionDelegate is the (very) rough equivalent of delegate void myFunctionDelegate<T>(T arg)
std::function<void(T)> follows value semantics (it behaves more like an int than a C# object reference) which makes things different.
A lambda closure ([](T t){/*code*/}) whose lifetime (or copies of it) outlives the local scope should not use & based capture. Instead use = based capture (which may require extra work). If the code you are calling does not store a copy of the delegate beyond the lifetime of the call, [&] is optimal. In C++ the lifetime of data is something you need concern yourself with.
This is not intended as a full tutorial on how lambdas and std::function work, but just to point you in the right direction.
I had thought that Generics in C# were implemented such that a new class/method/what-have-you was generated, either at run-time or compile-time, when a new generic type was used, similar to C++ templates (which I've never actually looked into and I very well could be wrong, about which I'd gladly accept correction).
But in my coding I came up with an exact counterexample:
static class Program {
static void Main()
{
Test testVar = new Test();
GenericTest<Test> genericTest = new GenericTest<Test>();
int gen = genericTest.Get(testVar);
RegularTest regTest = new RegularTest();
int reg = regTest.Get(testVar);
if (gen == ((object)testVar).GetHashCode())
{
Console.WriteLine("Got Object's hashcode from GenericTest!");
}
if (reg == testVar.GetHashCode())
{
Console.WriteLine("Got Test's hashcode from RegularTest!");
}
}
class Test
{
public new int GetHashCode()
{
return 0;
}
}
class GenericTest<T>
{
public int Get(T obj)
{
return obj.GetHashCode();
}
}
class RegularTest
{
public int Get(Test obj)
{
return obj.GetHashCode();
}
}
}
Both of those console lines print.
I know that the actual reason this happens is that the virtual call to Object.GetHashCode() doesn't resolve to Test.GetHashCode() because the method in Test is marked as new rather than override. Therefore, I know if I used "override" rather than "new" on Test.GetHashCode() then the return of 0 would polymorphically override the method GetHashCode in object and this wouldn't be true, but according to my (previous) understanding of C# generics it wouldn't have mattered because every instance of T would have been replaced with Test, and thus the method call would have statically (or at generic resolution time) been resolved to the "new" method.
So my question is this: How are generics implemented in C#? I don't know CIL bytecode, but I do know Java bytecode so I understand how Object-oriented CLI languages work at a low level. Feel free to explain at that level.
As an aside, I thought C# generics were implemented that way because everyone always calls the generic system in C# "True Generics," compared to the type-erasure system of Java.
In GenericTest<T>.Get(T), the C# compiler has already picked that object.GetHashCode should be called (virtually). There's no way this will resolve to the "new" GetHashCode method at runtime (which will have its own slot in the method-table, rather than overriding the slot for object.GetHashCode).
From Eric Lippert's What's the difference, part one: Generics are not templates, the issue is explained (the setup used is slightly different, but the lessons translate well to your scenario):
This illustrates that generics in C# are not like templates in C++.
You can think of templates as a fancy-pants search-and-replace
mechanism.[...] That’s not how generic types work; generic types are,
well, generic. We do the overload resolution once and bake in the
result. [...] The IL we’ve generated for the generic type already has
the method its going to call picked out. The jitter does not say
“well, I happen to know that if we asked the C# compiler to execute
right now with this additional information then it would have picked a
different overload. Let me rewrite the generated code to ignore the
code that the C# compiler originally generated...” The jitter knows
nothing about the rules of C#.
And a workaround for your desired semantics:
Now, if you do want overload resolution to be re-executed at runtime based on the runtime types of
the arguments, we can do that for you; that’s what the new “dynamic”
feature does in C# 4.0. Just replace “object” with “dynamic” and when
you make a call involving that object, we’ll run the overload
resolution algorithm at runtime and dynamically spit code that calls
the method that the compiler would have picked, had it known all the
runtime types at compile time.
I'm really blanking out here.
I'm wondering why I can't declare a delegate type within a method, but rather I have to do it at a class level.
namespace delegate_learning
{
class Program
{
// Works fine
public delegate void anon_delgate(int i);
static void Main(string[] args)
{
HaveFun();
Console.Read();
}
public static void HaveFun()
{
// Throws an error :/
//delegate void anon_delgate(int i);
anon_delgate ad = delegate(int i) { Console.WriteLine(i.ToString());};
}
}
}
Edit: I'm researching Lambda Expressions and backing up into how it was before Lambdas, for my own personal knowledge.
// Throws an error :/
delegate void anon_delgate(int i);
It throws an error, because it's a type definition, not a variable declaration. Any type definition is not allowed inside method. It's allowed only at class scope, or namespace scope.
namespace A
{
delegate void X(int i); //allowed
public class B
{
delegate void Y(int i); //also allowed
}
}
By the way, why don't you write this:
anon_delgate ad = i => Console.WriteLine(i.ToString());
It's called lambda expression.
You can't declare any type inside a method. So let's consider the question "why can I not declare a type inside a method in C#?"
The answer to questions of this form is always the same. In order for you to be able to do something in C#, the following things all have to happen:
Someone has to think of the feature
Someone has to design the feature
Someone has to write the specification of the feature
Someone has to implement that specification
Someone has to test the implementation
Someone has to document the feature (and translate the documentation into a dozen different languages.)
Somehow the implementation code has to get into a "vehicle" by which it can be shipped to customers.
So far, of the things on that list only the first one has happened. The rest of them haven't ever happened, so you can't use that feature in C#.
You seem to imply that the default state of a feature is "implemented" and that we have to come up with some reason to make it not implemented. I assure you that's not the case; the default state of all possible features is "not implemented", and we have to have a justification for spending the time, money and effort it takes to implement a feature. So far no one has made a compelling case that local type declarations are worthwhile; if you'd like to try to make a compelling case, I'd love to hear it.
Declaring a delegate inside a method would be like declaring a class inside a method because the compiler rewrites the delegate declaration onto a class declaration.
This is why you can't do this while it's perfectly valid do assign to a delegate type.
Being able to create arbitrary delegates any time you want is useful, but giving them distinct but anonymous types seems far less useful.
With or without lambdas, you could just replace anon_delgate ad with Action<int>. Since nobody outside method can see anon_delegate, its existence doesn't add extraordinary value. You want to define the delegate type locally, but you could encode any information about the purpose of the delegate inside the variable's name rather than in the variable's type. The dozens of already defined* Action and Func delegates make it very rare that you'll be unable to find a delegate that suits your needs.
In short, I see this feature as adding some heavy costs per Eric, but don't see it as adding enough benefits to offset those costs, nevermind offsetting the additional confusion that comes from providing another feature that might confuse developers.
This feature doesn't add any expressive power to the language, its nonexistence is easily worked around, and I think would waste more developer time (by making C# harder to learn/use) than it would save.
*(well, less of them in older versions of C#, but asking why a feature isn't in an older version of C# when it could be useful is pretty unexciting when the answer is, "wow, that is useful. We added it to the next version.")
Why don't you just use lambda expressions?
Action<int> ad = i => Console.WriteLine(i.ToString());
Because a delegate is a public method signature intended for a user of the class to comply with on their end. It's a way of saying "if you expose this method with these parameters, I can call it when necessary".
Method internals are not exposed outside of the class - just the signature - so declaring a method signature within what is private to the class doesn't make sense.
I understand delegates encapsulate method calls. However I'm having a hard time understanding their need. Why use delegates at all, what situations are they designed for?
A delegate is basically a method pointer. A delegate let us create a reference variable, but instead of referring to an instance of a class, it refers to a method inside the class. It refers any method that has a return type and has same parameters as specified by that delegate. It's a very very useful aspect of event. For thorough reading I would suggest you to read the topic in Head First C# (by Andrew Stellman and Jennifer Greene). It beautifully explains the delegate topic as well as most concepts in .NET.
Well, some common uses:
Event handlers (very common in UI code - "When the button is clicked, I want this code to execute")
Callbacks from asynchronous calls
Providing a thread (or the threadpool) with a new task to execute
Specifying LINQ projections/conditions etc
Don't think of them as encapsulating method calls. Think of them as encapsulating some arbitrary bit of behaviour/logic with a particular signature. The "method" part is somewhat irrelevant.
Another way of thinking of a delegate type is as a single-method interface. A good example of this is the IComparer<T> interface and its dual, the Comparison<T> delegate type. They represent the same basic idea; sometimes it's easier to express this as a delegate, and other times an interface makes life easier. (You can easily write code to convert between the two, of course.)
They are designed, very broadly speaking, for when you have code that you know will need to call other code - but you do not know at compile-time what that other code might be.
As an example, think of the Windows Forms Button.Click event, which uses a delegate. The Windows Forms programmers know that you will want something to happen when that button is pressed, but they have no way of knowing exactly what you will want done... it could be anything!
So you create a method and assign it to a delegate and set it to that event, and there you are. That's the basic reasoning for delegates, though there are lots of other good uses for them that are related.
Delegates are often used for Events. According to MSDN, delegates in .NET are designed for the following:
An eventing design pattern is used.
It is desirable to encapsulate a static method.
The caller has no need access other properties, methods, or interfaces on
the object implementing the method.
Easy composition is desired.
A class may need more than one implementation of the methodimplementation of the method
Another well put explanation from MSDN,
One good example of using a
single-method interface instead of a
delegate is IComparable or
IComparable. IComparable declares the
CompareTo method, which returns an
integer specifying a less than, equal
to, or greater than relationship
between two objects of the same type.
IComparable can be used as the basis
of a sort algorithm, and while using a
delegate comparison method as the
basis of a sort algorithm would be
valid, it is not ideal. Because the
ability to compare belongs to the
class, and the comparison algorithm
doesn’t change at run-time, a
single-method interface is ideal.single-method interface is ideal.
Since .NET 2.0 it has also been used for anonymous functions.
Wikipedia has a nice explanation about the Delegation pattern,
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. It passes the buck, so to speak (technically, an Inversion of Responsibility). The helper object is called the delegate. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.
Oversimplified: I'd say that a delegate is a placeholder for a function until that time when something assigns a real function to the delegate. Calling un-assigned delegates throws an exception.
Confusion occurs because there is often little difference made between the definition, declaration, instantiation and the invocation of delegates.
Definition:
Put this in a namespace as you would any class-definition.
public delegate bool DoSomething(string withThis);
This is comparable to a class-definition in that you can now declare variables of this delegate.
Declaration:
Put this is one of function routines like you would declare any variable.
DoSomething doSth;
Instantiation and assignment:
Usually you'll do this together with the declaration.
doSth = new DoSomething(MyDoSomethingFunc);
The "new DoSomething(..)" is the instantiation. The doSth = ... is the assignment.
Note that you must have already defined a function called "MyDoSomething" that takes a string and returns a bool.
Then you can invoke the function.
Invocation:
bool result = doSth(myStringValue);
Events:
You can see where events come in:
Since a member of a class is usually a declaration based upon a definition.
Like
class MyClass {
private int MyMember;
}
An event is a declaration based upon a delegate:
public delegate bool DoSomething(string withWhat);
class MyClass {
private event DoSomething MyEvent;
}
The difference with the previous example is that events are "special":
You can call un-assigned events without throwing an exception.
You can assign multiple functions to an event. They will then all get called sequentially. If one of those calls throws an exception, the rest doesn't get to play.
They're really syntactic sugar for arrays of delegates.
The point is of course that something/someone else will do the assigning for you.
Delegates allow you to pass a reference to a method. A common example is to pass a compare method to a sort function.
If you need to decide at runtime, which method to call, then you use a delegate. The delegate will then respond to some action/event at runtime, and call the the appropriate method. It's like sending a "delegate" to a wedding you don't want to attend yourself :-)
The C people will recognize this as a function pointer, but don't get caught up in the terminology here. All the delegate does (and it is actually a type), is provide the signature of the method that will later be called to implement the appropriate logic.
The "Illustrated C#" book by Dan Solis provides the easiest entry point for learning this concept that I have come across:
http://www.amazon.com/Illustrated-2008-Windows-Net-Daniel-Solis/dp/1590599543
A delegate is typically a combination of an object reference and a pointer to one of the object's class methods (delegates may be created for static methods, in which case there is no object reference). Delegates may be invoked without regard for the type of the included object, since the included method pointer is guaranteed to be valid for the included object.
To understand some of the usefulness behind delegates, think back to the language C, and the printf "family" of functions in C. Suppose one wanted to have a general-purpose version of "printf" which could not only be used as printf, fprintf, sprintf, etc. but could send its output to a serial port, a text box, a TCP port, a cookie-frosting machine, or whatever, without having to preallocate a buffer. Clearly such a function would need to accept a function pointer for the character-output routine, but that by itself would generally be insufficient.
A typical implementation (unfortunately not standardized) will have a general-purpose gp_printf routine which accepts (in addition to the format string and output parameters) a void pointer, and a pointer to a function which accepts a character and a void pointer. The gp_printf routine will not use the passed-in void pointer for any purpose itself, but will pass it to the character-output function. That function may then cast the pointer to a FILE* (if gp_printf is being called by fprintf), or a char** (if it's being called by sprintf), or a SERIAL_PORT* (if it's being called by serial_printf), or whatever.
Note that because any type of information could be passed via the void*, there would be no limit as to what gp_printf could do. There would be a danger, however: if the information passed in the void* isn't what the function is expecting, Undefined Behavior (i.e. potentially very bad things) would likely result. It would be the responsibility of the caller to ensure that the function pointer and void* are properly paired; nothing in the system would protect against incorrect usage.
In .net, a delegate would provide the combined functionality of the function pointer and void* above, with the added bonus that the delegate's constructor would ensure that the data was of the proper type for the function. A handy feature.