I've been playing with HttpWebRequests lately, and in the tutorials they always do:
IAsyncResult result = request.BeginGetResponse(
new AsyncCallback(UpdateItem),state);
But new AsyncCallback doesn't seem to be necesary. If UpdateItem has the right signature, then there doesn't seem to be a problem. So why do people include it? Does it do anything at all?
It's the same thing, mostly (there are a few overload rules to think about, although not in this simple example). But in previous versions of C#, there wasn't any delegate type inference. So the tutorial was either (a) written before delegate type inference was available, or (b) they wanted to be verbose for explanation purposes.
Here's a summary of a few of the different ways you can take advantage of delegate type inferencing:
// Old-school style.
Chef(new CookingInstructions(MakeThreeCourseMeal));
// Explicitly make an anonymous delegate.
Chef(delegate { MakeThreeCourseMeal });
// Implicitly make an anonymous delegate.
Chef(MakeThreeCourseMeal);
// Lambda.
Chef(() => MakeThreeCourseMeal());
// Lambda with explicit block.
Chef(() => { AssembleIngredients(); MakeThreeCourseMeal(); AnnounceDinnerServed(); });
AsyncCallback is just a delegate in C#, it is declared as
public delegate void AsyncCallback(IAsyncResult ar);
When you pass the method name itself as long as the signature matches the compiler will usually substitute the code for you, its just shortcut.
You can simply check this using Reflector. If you have this for example.
request.BeginGetResponse(TestMethod, null);
static void (IAsyncResult r)
{
//do something
}
The compiled code will actually look like this.
request.BeginGetResponse(new AsyncCallback(Test), null);
For completeness, this changes between C# 1.2 (with .NET 1.1) and C# 2.0 (with .NET 2.0). So from 2.0 onwards you can indeed omit the new SomeDelegateType(...) in most scenarios. Oddly, the tooling hasn't changed, so in the IDE if you type someObj.SomeEvent += the IDE will suggest (via tab tab) the full version including delegate type.
Related
Using Unity 2018-2017 with same problem on building for net-
error CS0117: 'Delegate' does not contain a definition for 'CreateDelegate'
This is the method:
private V CreateDelegate<V>(MethodInfo method, Object target) where V : class
{
var ret = (Delegate.CreateDelegate(typeof(V), target, method) as V);
if (ret == null)
{
throw new ArgumentException("Unabled to create delegate for method called " + method.Name);
}
return ret;
}
Building for UWP.
Using system.Linq
I tryed with "MethodInfo" but maybe some parameters are wrong.
This method isnĀ“t available?
Which platform/runtime are you targeting? I don't know about Mono, but .Net standard 1.x doesn't support Delegate.CreateDelegate. Always keep in mind that you're writing your code against a limited subset of the .Net framework. Also keep in mind that your code will inevitably be AOT-compiled on some platforms (il2cpp, iOS, etc.), so some reflection/emit features will be unavailable.
Note: AOT means ahead-of-time, meaning your code is compiled to machine instructions rather than an intermediate language. Reflection is when you use the code itself as data, so for example you can get a list of the properties a class defines. Emit means generating code at runtime. If you don't understand what those are, you should probably do some studying. It's well worth the effort in the long run.
1. Your return type is a class, not a delegate.
where V : class
So this method doesn't even make sense. You're going to get an invalid cast exception.
2. CreateDelegate takes 2 parameters, not 3.
I'm not even sure what purpose target even serves here, so I can't even guess what you're trying to do.
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 was looking at the implemention of
Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove)
and I'm struggling to grasp how it works. Lets says that TEventHandler is the standard:
public delegate void EventHandler(object sender, EventArgs e);
then the code that is puzzling me is:
TEventHandler d = (TEventHandler) Delegate.CreateDelegate(
typeof (TEventHandler),
(object) new Action<EventArgs>(observer.OnNext),
typeof (Action<EventArgs>).GetMethod("Invoke"));
(n.b I've specialised this generic code to this specific example instance.)
How is it that CreateDelegate is creating a delegate of signature (obj, args) that is bound to an invoke method of signature (args) on the action? Where is obj going?
It feels a bit like it might be around having an open delegate on action and we are coercing the 'this' to be 'firstArguemnt' from CreateDelegate and allowing the args to fall through. If so feels kinda dirty?
Let's break it down:
Firstly, decompiling Rx v2.0.3 doesn't seem to have a Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove) method, and neither does Rx v 1.1 which I happened to have lying around. I'm going to assume you mean the nearest match I can find, which is this:
public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
Looking at the decompiled source for Rx 1.1 (the 2.0 source has gone all architecture astronaut on us and is full of indirection which makes it much harder to follow) The actual code snippet using reflector to decompile is this:
Action<TEventArgs> o = new Action<TEventArgs>(observer.OnNext);
TDelegate d = CreateDelegate<TDelegate>(o,
typeof(Action<TEventArgs>).GetMethod("Invoke"));
addHandler(d);
So, the question:
How is it that CreateDelegate is creating a delegate of signature (obj, args) that is bound to an invoke method of signature (args) on the action? Where is obj going?
I'm not sure if I've understood quite correctly, but it seems like the question specifically is something like How does CreateDelegate<TDelegate>(o, typeof(Action<TEventArgs>).GetMethod("Invoke") produce a method with only the args parameter - what happens to the o object?
What's happening is that yes, the o object is being passed as object firstArgument to the internal .NET framework method.
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)
This method "binds" the firstArgument as basically being the this pointer for the returned method. Internally it will store a reference to the firstArgument somewhere inside the delegate object. We can't see inside that as it's an internal .NET implementation detail and so it can do all sorts of odd things and break rules where it pleases.
It feels a bit like it might be around having an open delegate on action and we are coercing the 'this' to be 'firstArguemnt' from CreateDelegate and allowing the args to fall through. If so feels kinda dirty?
Yes, that's pretty much exactly what's happening. This is what that CreateDelegate function is designed to do.
Except it gets even dirtier than that. CreateDelegate simply returns an object of type Delegate - we have no type safety on the method args, etc - and then the code casts it into a TDelegate - this works because delegate is special and you can cast it to any function type that has the same "shape". As above, it's an internal .NET implementation detail and so it can do all sorts of weird things :-)
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.
Consider the code below. Looks like perfectly valid C# code right?
//Project B
using System;
public delegate void ActionSurrogate(Action addEvent);
//public delegate void ActionSurrogate2();
// Using ActionSurrogate2 instead of System.Action results in the same error
// Using a dummy parameter (Action<double, int>) results in the same error
// Project A
public static class Class1 {
public static void ThisWontCompile() {
ActionSurrogate b = (a) =>
{
a(); // Error given here
};
}
}
I get a compiler error 'Delegate 'Action' does not take 0 arguments.' at the indicated position using the (Microsoft) C# 4.0 compiler. Note that you have to declare ActionSurrogate in a different project for this error to manifest.
It gets more interesting:
// Project A, File 1
public static class Class1 {
public static void ThisWontCompile() {
ActionSurrogate b = (a) => { a(); /* Error given here */ };
ActionSurrogate c = (a) => { a(); /* Error given here too */ };
Action d = () => { };
ActionSurrogate c = (a) => { a(); /* No error is given here */ };
}
}
Did I stumble upon a C# compiler bug here?
Note that this is a pretty annoying bug for someone who likes using lambdas a lot and is trying to create a data structures library for future use... (me)
EDIT: removed erronous case.
I copied and stripped my original project down to the minimum to make this happen. This is literally all the code in my new project.
FINAL UPDATE:
The bug has been fixed in C# 5. Apologies again for the inconvenience, and thanks for the report.
Original analysis:
I can reproduce the problem with the command-line compiler. It certainly looks like a bug. It's probably my fault; sorry about that. (I wrote all of the lambda-to-delegate conversion checking code.)
I'm in a coffee shop right now and I don't have access to the compiler sources from here. I'll try to find some time to reproduce this in the debug build tomorrow and see if I can work out what's going on. If I don't find the time, I'll be out of the office until after Christmas.
Your observation that introducing a variable of type Action causes the problem to disappear is extremely interesting. The compiler maintains many caches for both performance reasons and for analysis required by the language specification. Lambdas and local variables in particular have lots of complex caching logic. I'd be willing to bet as much as a dollar that some cache is being initialized or filled in wrong here, and that the use of the local variable fills in the right value in the cache.
Thanks for the report!
UPDATE: I am now on the bus and it just came to me; I think I know exactly what is wrong. The compiler is lazy, particularly when dealing with types that came from metadata. The reason is that there could be hundreds of thousands of types in the referenced assemblies and there is no need to load information about all of them. You're going to use far less than 1% of them probably, so let's not waste a lot of time and memory loading stuff you're never going to use. In fact the laziness goes deeper than that; a type passes through several "stages" before it can be used. First its name is known, then its base type, then whether its base type hierarchy is well-founded (acyclic, etc), then its type parameter constraints, then its members, then whether the members are well-founded (that overrides override something of the same signature, and so on.) I'll bet that the conversion logic is failing to call the method that says "make sure the types of all the delegate parameters have their members known", before it checks the signature of the delegate invoke for compatibility. But the code that makes a local variable probably does do that. I think that during the conversion checking, the Action type might not even have an invoke method as far as the compiler is concerned.
We'll find out shortly.
UPDATE: My psychic powers are strong this morning. When overload resolution attempts to determine if there is an "Invoke" method of the delegate type that takes zero arguments, it finds zero Invoke methods to choose from. We should be ensuring that the delegate type metadata is fully loaded before we do overload resolution. How strange that this has gone unnoticed this long; it repros in C# 3.0. Of course it does not repro in C# 2.0 simply because there were no lambdas; anonymous methods in C# 2.0 require you to state the type explicitly, which creates a local, which we know loads the metadata. But I would imagine that the root cause of the bug - that overload resolution does not force loading metadata for the invoke - goes back to C# 1.0.
Anyway, fascinating bug, thanks for the report. Obviously you've got a workaround. I'll have QA track it from here and we'll try to get it fixed for C# 5. (We have missed the window for Service Pack 1, which is already in beta.)
This probably is a problem with type inference, apperently the compiler infers a as an Action<T> instead of Action (it might think a is ActionSurrogate, which would fit the Action<Action>> signature). Try specifying the type of a explicitly:
ActionSurrogate b = (Action a) =>
{
a();
};
If this is not the case - might check around your project for any self defined Action delegates taking one parameter.
public static void ThisWontCompile()
{
ActionSurrogate b = (Action a) =>
{
a();
};
}
This will compile. Some glitch with the compiler its unable to find the Action delegate without parameters. That's why you are getting the error.
public delegate void Action();
public delegate void Action<T>();
public delegate void Action<T1,T2>();
public delegate void Action<T1,T2,T3>();
public delegate void Action<T1,T2,T3,T4>();