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".
Related
I made a method to loop and clear all textbox controls in my form.
Controls.OfType<TextBox>()
.ToList()
.ForEach(tb => tb.Clear());
This works just fine, but I figured that since the first argument passed to any instance method is always a reference to the instance that I should be able to write it like this
Controls.OfType<TextBox>()
.ToList()
.ForEach(TextBox.Clear);
Unfortunately that doesn't actually work, and I don't quite understand why..
It would work if TextBox.Clear was a static method with a TextBox parameter; but instead, it's an instance method with no parameters, so the compiler can't automatically transform it to an Action<TextBox>.
Note that the CLR does support open-instance delegates (you can create one with the Delegate.CreateDelegate method), but the C# language doesn't support it.
Here's how to create an open-instance delegate that will invoke TextBox.Clear on its argument:
var action = (Action<TextBox>)Delegate.CreateDelegate(
typeof(Action<TextBox>),
null,
typeof(TextBox).GetMethod("Clear"));
The this parameter is implicit, not explicit. Foreach is expecting a method with an explicit parameter, not an implicit one.
As for why the C# language team didn't implement this feature, you'll have to ask them. They of course could have designed the language to support this, if they wanted to. There's no real point in us speculating as to why they didn't.
Strings are reference types, but they are immutable. This allows for them to be interned by the compiler; everywhere the same string literal appears, the same object may be referenced.
Delegates are also immutable reference types. (Adding a method to a multicast delegate using the += operator constitutes assignment; that's not mutability.) And, like, strings, there is a "literal" way to represent a delegate in code, using a lambda expression, e.g.:
Func<int> func = () => 5;
The right-hand side of that statement is an expression whose type is Func<int>; but nowhere am I explicitly invoking the Func<int> constructor (nor is an implicit conversion happening). So I view this as essentially a literal. Am I mistaken about my definition of "literal" here?
Regardless, here's my question. If I have two variables for, say, the Func<int> type, and I assign identical lambda expressions to both:
Func<int> x = () => 5;
Func<int> y = () => 5;
...what's preventing the compiler from treating these as the same Func<int> object?
I ask because section 6.5.1 of the C# 4.0 language specification clearly states:
Conversions of semantically identical
anonymous functions with the same
(possibly empty) set of captured outer
variable instances to the same
delegate types are permitted (but not
required) to return the same delegate
instance. The term semantically
identical is used here to mean that
execution of the anonymous functions
will, in all cases, produce the same
effects given the same arguments.
This surprised me when I read it; if this behavior is explicitly allowed, I would have expected for it to be implemented. But it appears not to be. This has in fact gotten a lot of developers into trouble, esp. when lambda expressions have been used to attach event handlers successfully without being able to remove them. For example:
class EventSender
{
public event EventHandler Event;
public void Send()
{
EventHandler handler = this.Event;
if (handler != null) { handler(this, EventArgs.Empty); }
}
}
class Program
{
static string _message = "Hello, world!";
static void Main()
{
var sender = new EventSender();
sender.Event += (obj, args) => Console.WriteLine(_message);
sender.Send();
// Unless I'm mistaken, this lambda expression is semantically identical
// to the one above. However, the handler is not removed, indicating
// that a different delegate instance is constructed.
sender.Event -= (obj, args) => Console.WriteLine(_message);
// This prints "Hello, world!" again.
sender.Send();
}
}
Is there any reason why this behavior—one delegate instance for semantically identical anonymous methods—is not implemented?
You're mistaken to call it a literal, IMO. It's just an expression which is convertible to a delegate type.
Now as for the "interning" part - some lambda expressions are cached , in that for one single lambda expression, sometimes a single instance can be created and reused however often that line of code is encountered. Some are not treated that way: it usually depends on whether the lambda expression captures any non-static variables (whether that's via "this" or local to the method).
Here's an example of this caching:
using System;
class Program
{
static void Main()
{
Action first = GetFirstAction();
first -= GetFirstAction();
Console.WriteLine(first == null); // Prints True
Action second = GetSecondAction();
second -= GetSecondAction();
Console.WriteLine(second == null); // Prints False
}
static Action GetFirstAction()
{
return () => Console.WriteLine("First");
}
static Action GetSecondAction()
{
int i = 0;
return () => Console.WriteLine("Second " + i);
}
}
In this case we can see that the first action was cached (or at least, two equal delegates were produced, and in fact Reflector shows that it really is cached in a static field). The second action created two unequal instances of Action for the two calls to GetSecondAction, which is why "second" is non-null at the end.
Interning lambdas which appear in different places in the code but with the same source code is a different matter. I suspect it would be quite complex to do this properly (after all, the same source code can mean different things in different places) and I would certainly not want to rely on it taking place. If it's not going to be worth relying on, and it's a lot of work to get right for the compiler team, I don't think it's the best way they could be spending their time.
Is there any reason why this behavior—one delegate instance for semantically identical anonymous methods—is not implemented?
Yes. Because spending time on a tricky optimization that benefits almost no one takes time away from designing, implementing, testing and maintaining features that do benefit people.
The other answers bring up good points. Mine really doesn't have to do with anything technical - Every feature starts out with -100 points.
In general, there is no distinction between string variables which refer to the same String instance, versus two variables which refer to different strings that happen to contain the same sequence of characters. The same is not true of delegates.
Suppose I have two delegates, assigned to two different lambda expressions. I then subscribe both delegates to an event handler, and unsubscribe one. What should be the result?
It would be useful if there were a way in vb or C# to designate that an anonymous method or lambda which does not make reference to Me/this should be regarded as a static method, producing a single delegate which could be reused throughout the life of the application. There is no syntax to indicate that, however, and for the compiler to decide to have different lambda expressions return the same instance would be a potentially breaking change.
EDIT I guess the spec allows it, even though it could be a potentially breaking change if any code were to rely upon the instances being distinct.
This is allowed because the C# team cannot control this. They heavily rely on the implementation details of delegates (CLR + BCL) and the JIT compiler's optimizer. There already is quite a proliferation of CLR and jitter implementations right now and there is little reason to assume that's going to end. The CLI spec is very light on rules about delegates, not nearly strong enough to ensure all these different teams will end up with an implementation that guarantees that delegate object equality is consistent. Not in the least because that would hamper future innovation. There's lots to optimize here.
Lambdas can't be interned because they use an object to contain the captured local variables. And this instance is different every time you you construct the delegate.
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'.
Method overloading allows us to define many methods with the same name but with a different set of parameters ( thus with the same name but different signature ).
Are these two methods overloaded?
class A
{
public static void MyMethod<T>(T myVal) { }
public static void MyMethod(int myVal) { }
}
EDIT:
Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same name and same signature?
Are the two methods overloaded?
Yes.
Shouldn't statement A<int>.MyMethod(myInt); throw an error, since constructed type A<int> has two methods with the same signature?
The question doesn't make sense; A is not a generic type as you have declared it. Perhaps you meant to ask:
Should the statement A.MyMethod(myInt); cause the compiler to report an error, since there are two ambiguous candidate methods?
No. As others have said, overload resolution prefers the non-generic version in this case. See below for more details.
Or perhaps you meant to ask:
Should the declaration of type A be illegal in the first place, since in some sense it has two methods with the same signature, MyMethod and MyMethod<int>?
No. The type A is perfectly legal. The generic arity is part of the signature. So there are not two methods with the same signature because the first has generic arity zero, the second has generic arity one.
Or perhaps you meant to ask:
class G<T>
{
public static void M(T t) {}
public static void M(int t) {}
}
Generic type G<T> can be constructed such that it has two methods with the same signature. Is it legal to declare such a type?
Yes, it is legal to declare such a type. It is usually a bad idea, but it is legal.
You might then retort:
But my copy of the C# 2.0 specification as published by Addison-Wesley states on page 479 "Two function members declared with the same names ... must have have parameter types such that no closed constructed type could have two members with the same name and signature." What's up with that?
When C# 2.0 was originally designed that was the plan. However, then the designers realized that this desirable pattern would be made illegal:
class C<T>
{
public C(T t) { ... } // Create a C<T> from a given T
public C(Stream s) { ... } // Deserialize a C<T> from disk
}
And now we say sorry buddy, because you could say C<Stream>, causing two constructors to unify, the whole class is illegal. That would be unfortunate. Obviously it is unlikely that anyone will ever construct this thing with Stream as the type parameter!
Unfortunately, the spec went to press before the text was updated to the final version. The rule on page 479 is not what we implemented.
Continuing to pose some more questions on your behalf:
So what happens if you call G<int>.M(123) or, in the original example, if you call A.MyMethod(123)?
When overload resolution is faced with two methods that have identical signatures due to generic construction then the one that is generic construction is considered to be "less specific" than the one that is "natural". A less specific method loses to a more specific method.
So why is it a bad idea, if overload resolution works?
The situation with A.MyMethod isn't too bad; it is usually pretty easy to unambiguously work out which method is intended. But the situation with G<int>.M(123) is far worse. The CLR rules make this sort of situation "implementation defined behaviour" and therefore any old thing can happen. Technically, the CLR could refuse to verify a program that constructs type G<int>. Or it could crash. In point of fact it does neither; it does the best it can with the bad situation.
Are there any examples of this sort of type construction causing truly implementation-defined behaviour?
Yes. See these articles for details:
https://ericlippert.com/2006/04/05/odious-ambiguous-overloads-part-one/
https://ericlippert.com/2006/04/06/odious-ambiguous-overloads-part-two/
Yes. MyMethod(int myVal) will be called when the type of the parameter is an int, the generic overload will be called for all other parameter arguments, even when the parameter argument is implicitly convertible to (or is a derived class of) the hardcoded type. Overload resolution will go for the best fit, and the generic overload will resolve to an exact match at compile time.
Note: You can explicitly invoke the generic overload and use an int by providing the type parameter in the method call, as Steven Sudit points out in his answer.
short s = 1;
int i = s;
MyMethod(s); // Generic
MyMethod(i); // int
MyMethod((int)s); // int
MyMethod(1); // int
MyMethod<int>(1); // Generic**
MyMethod(1.0); // Generic
// etc.
Yes, they are. They will allow code as such:
A.MyMethod("a string"); // calls the generic version
A.MyMethod(42); // calls the int version
Yes, they are overloaded. The compiler is supposed to prefer explicit method signatures against generic methods if they are available. Beware, however, that if you can avoid this kind of overload you probably should. There have been bug reports with respect to this sort of overload and unexpected behaviors.
https://connect.microsoft.com/VisualStudio/feedback/details/522202/c-3-0-generic-overload-call-resolution-from-within-generic-function
Yes. They have the same name "MyMethod" but different signatures. The C# specification, however, specifically handles this by saying that the compiler will prefer the non-generic version over the generic version, when both are options.
Yes. Off the top of my head, if you call A.MyMethod(1);, it will always run the second method. You'd have to call A.MyMethod<int>(1); to force it to run the first.
How does the system know what to use when 'this' keyword is used?
Recently, I was asked this question in an interview. Having never thought about this, I replied back saying that the system will know the current context in which the flow of control is and decide the object to be used instead of this. The interviewer didn't look pleased and he moved on to the next question.
Can anyone tell me what did the interviewer may have wanted to ask and what would be the answer?
(I think this can interpreted in different ways and hence keeping this as wiki unless someone point out not to..)
Though the answers which point out that the "this" reference is essentially passed as a magic "hidden parameter" to the call are essentially correct, the full story is actually quite a bit more complicated in C# than one might think at first glance.
Reference types are straightforward; the referenced object is checked for null and then conceptually passed as an unnamed, non-variable parameter called "this". The story is complicated by value types.
Remember, value types are, by definition, passed by value -- that is, passed by making a copy of the data. Hence their name. But clearly mutable value types -- which are pure evil and should be avoided -- cannot be passed by value as the "this", because if you called a mutator, the "this" in the mutator method would be mutating the copy, not the original!
Therefore, in a value type's method call, "this" is not the value of the receiver, it is an alias to the variable representing the storage location of the receiver. We implement this by passing "this" as the managed address of the receiver, not the value of the receiver.
Now we can raise another difficulty. What if the variable storing the value being mutated is a read-only variable? Now what do we do? If you're curious, read my article on the subject and see if you can correctly answer the puzzle presented:
http://blogs.msdn.com/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx
The this keyword is a pointer to the current object. All non-static member functions of a class have access to a this pointer.
The pointer to the current object is normally made available by the compiler in a non-static member function by using a register, usually ECX. So when you write this in a non-static member function the compiler will translate that call into loading the address from ECX.
Check this simple example:
A t;
t.Test();
004114DE lea ecx,[t]
004114E1 call std::operator > (41125Dh)
Before calling the non-static member function Test() the compiler loads the register ECX with [t] (the address of variable t - will be this inside Test method).
004114DE lea ecx,[t]
And inside the function it can use ecx to obtain the address for the current object instance.
this is a hidden parameter in all methods of an object and contains a copy of the instance pointer.
Consider this class
class A {
private:
int data;
public:
void SetData(int arg) {
this->data = arg;
}
}
and this code that calls SetData():
A objA;
objA.SetData(1);
When the above code is compiled, the compiler emits something equivalent to this for the member function:
void SetData(A* this, int arg) {
this->data = arg;
}
And the calling code is converted to something like this:
A objA;
SetData(&objA, 1);
What this means is that upon compilation:
Member functions are converted to simple, global functions.
The class instance to which member functions "belong" is simply passed as the first argument to them (or rather its address is passed).
So in conclusion, what you refer to as this pointer in your code simply ends being the the first argument to the function. This is how the "system knows" which object to access through the "this" pointer.
The above example is of C++. If you for a moment forget about the CLR and the JITting and all that, what happens in C# is conceptually the same thing.
At run time "this" will resolve to the pointer to the current object, therefore "the system" will be able to call a respective method on that object.
I would have answered "It is a reference to the instance of the current class."
Dan
The compiler takes care of correctly resolving that reference at compile time. If you want to know more information about some of the techniques they use to do this, this book will tell you everything you need to know:
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
in c the this pointer is an invisible pointer argument to your class.
So in essence the first argument to a class method is the pointer to the class itself. You reference it by using this.
My answer would have been "Who cares? It knows. If I ever need to find out in more detail I'll Google it."
You obviously know what the effect of using "this" would be, which surely is the important thing. For 99% of programming tasks I would have thought that the detail of how it is resolved internally is trivia.
Shematicaly compiler converts such code:
pObject->someMethod(A,B,C)
Into such code if 'someMethod' is not virtual:
someMethod(pObject,A,B,C)
Or into such code if 'someMethod' is virtual:
(*pObject->vtable[someMethodIndex]) (pObject, A,B,C)
And everywhere you place 'this' keyword first parameter is used instead of it;
Of course compiler may optimize/simplify by removing first argument and use some CPU register (normally esx) to store object's address.
The "this" operator will point to the current object. An example where the presence of a "this" operator will make a difference is this:
public class MyClass
{
int value;
public void Test(int value)
{
MessageBox.Show(value); // Will show the parameter to the function
MessageBox.Show(this.value); // Will show the field in the object
}
}
Note that the "this" operator will not change what virtual function will be called if it is overridden in a child class
public class MyClass
{
public virtual void Test() {}
public void CallTest()
{
this.Test();
}
}
public class MyClass2 : MyClass
{
public override void Test() {}
}
If you execute the following code
MyClass c = new MyClass2();
c.CallTest();
will still call the MyClass2.Test() and not MyClass.Test()
So the "this" operator simply tells you, that you are accessing something declared at class level.