Hi
I have a little problem with understanding this kind of syntax
public delegate void DelegateType();
BeginInvoke(new DelegateType(functionName));
Could somebody tell me what exectly mean new DelegateType(functionName). Why do I have to use new keyword ??
See the documentation.
A delegate is a type that holds a method.
You're creating a new instance of a delegate type, pointing to an existing method.
C# 2 adds an implicit conversion from a method group to any matching delegate type.
However, since BeginInvoke doesn't take a specific delegate type (such as System.Action), you always need to explicitly create a delegate instance.
The first statement declares a delegate type, the second statement instantiates a new delegate of DelegateType.
From the corresponding MSDN article (read the article for more information!):
Once a delegate type has been
declared, a delegate object must be
created and associated with a
particular method. Like all other
objects, a new delegate object is
created with a new expression. When
creating a delegate, however, the
argument passed to the new expression
is special — it is written like a
method call, but without the arguments
to the method.
public delegate void DelegateType();
This defines the syntax for a delegate. This is a reference to a method, either static, or an instance method.
When you call BeginInvoke, you're passing a delegate as the parameter. The C# compiler will convert from any explicit delegate type to System.Delegate, but since the parameter is defined as taking any delegate (via System.Delegate), you must explicitly define the type.
When you specify:
new DelegateType(functionName)
You're creating a delegate of a specific type (DelegateType), which is then passed to the function.
Often, newer APIs will use a known type, such as System.Action (which has the same syntax as your DelegateType). If a method takes an "Action", you would not need the definition above, and you could do:
CallMethodTakingAction(functionName);
'DelegateType' is only a type of thing, so like any other type, you want to say "here's one instance of this type", you need to use 'new'.
Related
I'm trying to create a Standard library with common types for WPF/UWP etc.
Since many types are not in Standard, sometimes you have to use reflection.
In this connection, the task of creating a DispatchedHandler from an Action arose.
In UWP, this is easy: new DispatchedHandler(action);.
But in Standard I only have Type from DispatchedHandler.
private object GetDispatchedHandler(Action action)
{
// Some code
dispatchedHandlerType = windowsAssembly.GetType("Windows.UI.Core.DispatchedHandler");
// Next, you need to transform the `action` and return it from the method.
return Activator.CreateInstance(dispatchedHandlerType, action);
}
This code throws an exception: "Constructor on type 'Windows.UI.Core.DispatchedHandler' not found".
But can get a constructor from a type: dispatchedHandlerType.GetConstructors()[0].
The constructor has the following signature: {Void .ctor(System.Object, IntPtr)}.
The first parameter, I think, should be passed action.
What should be passed as the second parameter?
dispatchedHandlerConsructor.Invoke(new object[] { action, ??? });
DispatchedHandler is a delegate type. It doesn't take an Action; it basically is the same thing as Action, but in an incompatible delegate type. The parameters here are the target instance and the function-pointer. You can create arbitrary delegate instances via Delegate.CreateDelegate. Usually you would create this type directly from a target method and instance, and never create the Action, however in this case you may also be able to simply pass in the .Target and .Method from the Action into your call to Delegate.CreateDelegate, since the signature is the same:
var del = Delegate.CreateDelegate(dispatchedHandlerType, action.Target, action.Method);
Given this code:
class C
{
C()
{
Test<string>(A); // fine
Test((string a) => {}); // fine
Test((Action<string>)A); // fine
Test(A); // type arguments cannot be inferred from usage!
}
static void Test<T>(Action<T> a) { }
void A(string _) { }
}
The compiler complains that Test(A) can't figure out T to be string.
This seems like a pretty easy case to me, and I swear I've relied far more complicated inference in other generic utility and extension functions I've written. What am I missing here?
Update 1: This is in the C# 4.0 compiler. I discovered the issue in VS2010 and the above sample is from a simplest-case repro I made in LINQPad 4.
Update 2: Added some more examples to the list of what works.
Test(A);
This fails because the only applicable method (Test<T>(Action<T>)) requires type inference, and the type inference algorithm requires that each each argument be of some type or be an anonymous function. (This fact is inferred from the specification of the type inference algorithm (§7.5.2)) The method group A is not of any type (even though it is convertable to an appropriate delegate type), and it is not an anonymous function.
Test<string>(A);
This succeeds, the difference being that type inference is not necessary to bind Test, and method group A is convertable to the required delegate parameter type void Action<string>(string).
Test((string a) => {});
This succeeds, the difference being that the type inference algorithm makes provision for anonymous functions in the first phase (§7.5.2.1). The parameter and return types of the anonymous function are known, so an explicit parameter type inference can be made, and a correspondense is thereby made between the types in the anonymous function (void ?(string)) and the type parameter in the delegate type of the Test method’s parameter (void Action<T>(T)). No algorithm is specified for method groups that would correspond to this algorithm for anonymous functions.
Test((Action<string>)A);
This succeeds, the difference being that the untyped method group parameter A is cast to a type, thereby allowing the type inference of Test to proceed normally with an expression of a particular type as the only argument to the method.
I can think of no reason in theory why overload resolution could not be attempted on the method group A. Then—if a single best binding is found—the method group could be given the same treatment as an anonymous function. This is especially true in cases like this where the method group contains exactly one candidate and it has no type parameters. But the reason it does not work in C#4 appears to be the fact that this feature was not designed and implemented. Given the complexity of this feature, the narowness of its application, and the existance of three easy work-arounds, I am not going to be holding my breath for it!
I think it's because it's a two-step inference:
It has to infer that you want to convert A to a generic delegate
It has to infer what the type of the delegate parameter should be
I'm not sure if this is the reason, but my hunch is that a two-step inference isn't necessarily easy for the compiler.
Edit:
Just a hunch, but something is telling me the first step is the problem. The compiler has to figure out to convert to a delegate with a different number of generic parameters, and so it can't infer the types of the parameters.
This looks like a vicious circle to me.
Test method expects a parameter of delegate type constructed from generic type Action<T>. You pass in a method group instead: Test(A). This means compiler has to convert your parameter to a delegate type (method group conversion).
But which delegate type? To know the delegate type we need to know T. We didn't specify it explicitly, so compiler has to infer it to figure out the delegate type.
To infer the type parameters of the method we need to know the types of the method arguments, in this case the delegate type. Compiler doesn't know the argument type and thus fails.
In all other cases either type of argument is apparent:
// delegate is created out of anonymous method,
// no method group conversion needed - compiler knows it's Action<string>
Test((string a) => {});
// type of argument is set explicitly
Test((Action<string>)A);
or type parameter is specified explicitly:
Test<string>(A); // compiler knows what type of delegate to convert A to
P.S. more on type inference
You're passing the name of the Method A. The .Net framework CAN convert it to an Action, but it's implicit and it will not take responsibility for it.
But still, a method name is NOT an explicit Action<> Object. And therefor it won't infer the type as an Action type.
I could be wrong, but I imagine the real reason C# cannot infer the type is due to method overloading and the ambiguity that arises. For example, suppose I have the following methods: void foo (int) and void foo (float). Now if I write var f = foo. Which foo should the compiler pick? Likewise, the same problem happens with your example using Test(foo).
I've used short.Parse(somestring) in the past. But recently I've seen a confusing usage of short.Parse() like below:
var shortArray = Array.ConvertAll(stringArr, short.Parse);
So, Array.ConvertAll expects an array and a converter. Well, fine! But how are we passing the short.Parse as (or like) a property? I don't find such a property in Int16 struct. So, what is happening here actually?
Array.ConvertAll takes an instance of a Converter<TIn, TOut> delegate as its second parameter. The signature of this delegate is substantially the same as short.Parse - both return a value for a single argument.
The compiler will convert a 'method group' to a compatible delegate. This is known as implicit method group conversion.
For comparison, the explicit creation of the delegate would look like this:
Array.ConvertAll(stringArr, new Converter<string, short>(short.Parse));
So, to answer you question: it's still a method, not a property. What you are doing here is passing the method as a delegate. You are providing ConvertAll with a function to call: when it converts an element in the source array, it will execute short.Parse(element) and use the value returned in the new array.
short.Parse is a method. But it is possible to pass a method as an argument.
Note the difference between calling a method and passing the value returned by that method (short.Parse()), and passing the method itself (short.Parse).
Internally, this would be passing the address of the method so that the receiver of that argument can call it.
Just terminology...from what I understand, delegate is type and one needs to have its instance. Thus I do not assign method to delegate but to instance of that delegate, is that right? Seems that on MSDN they are sloppy or I did not understand it well.
That's close to right. You have an immutable delegate instance. And you can add methods which have the same signatures as the delegate type to it, which creates new delegate instances. So for example with a delegate type Func<int>:
Func<int> f;
An instance doesn't exist yet.
f = () => 5;
Now we have an instance of it.
f += () => 6;
The old instance is gone and now we have a new one. But when you call f() both methods will be executed. The return value will be that of the last one added to the delegate instance.
Well, yes and no. The "delegate" as the term is most often used refers to the "method reference" which you might call the "delegate instance". In the logical sense, this instance is the "delegate"; it refers to the actual method which callers will utilize to perform some task they can't or shouldn't do themselves.
When you define public delegate void MyDelegate();, you are defining a "delegate type", which states the proper signature of methods that can be used as delegates in this case. It's the difference between a class and an object; a class is the template, an object is an instance conforming to the template.
The term "delegate" is used to refer to two different things:
A static class which defines a method signature and return type, and includes some 'glue' logic.
An instance of an object with an Invoke method whose function signature matches that of a static class described above.
Unfortunately, I'm unaware of any standard nomenclature to distinguish them, but perhaps one might use the terms "Delegate signature" and either "ActionDelegate" or "FunctionDelegate".
Incidentally, the terms "object", "reference", and "destructor" cause similar confusion. I prefer to use the phrase "object ID" to refer to the variables which point at "object instances", use the term "reference" exclusively for pass-by-reference parameter semantics, and avoid "destructor" altogether in favor of "finalizer" and "disposer".
I've seen this syntax a couple times now, and it's beginning to worry me,
For example:
iCalendar iCal = new iCalendar();
Event evt = iCal.Create<Event>();
It's a Generic Method, Create is declared with type parameters, and check this links for more information:
An Introduction to C# Generics
Generics (C# Programming Guide)
Generic Methods
It's calling a generic method - so in your case, the method may be declared like this:
public T Create<T>()
You can specify the type argument in the angle brackets, just as you would for creating an instance of a generic type:
List<Event> list = new List<Event>();
Does that help?
One difference between generic methods and generic types is that the compiler can try to infer the type argument. For instance, if your Create method were instead:
public T Copy<T>(T original)
you could just call
Copy(someEvent);
and the compiler would infer that you meant:
Copy<Event>(someEvent);
It's the way you mention a generic method in C#.
When you define a generic method you code like this:
return-type MethodName<type-parameter-list>(parameter-list)
When you call a generic method, the compiler usually infers the type parameter from the arguments specified, like this example:
Array.ForEach(myArray, Console.WriteLine);
In this example, if "myArray" is a string array, it'll call Array.ForEach<string> and if it's an int array, it'll call Array.ForEach<int>.
Sometimes, it's impossible for the compiler to infer the type from the parameters (just like your example, where there are no parameters at all). In these cases, you have to specify them manually like that.
It is a generic method that implements the Factory Method pattern.
This syntax is just applying generics to a method. It's typically used for scenarios where you want to control the return type of the method. You will find this kind of syntax a lot in code that uses a IoC framework.