SamSam698

Good moring!

When I read a line of C# code about delegate,I found it interesting in below code:

//other code goes here
delegate void DrawShape(Brush aBrush,Rectangle aRect);
//other code goes here
DrawShape DrawRectangleMethod;
DrawRectangleMethod=new DrawShape(aGraphics.FillRectangle);
MyDrawShape(DrawRectangleMethod);
//other code goes here
private void MyDrawShape(DrawShape theDelegate)
{/* */}

Big surprise the above code can compile without even a warning!!My question is that the signature of the delegate DrawShape have two parms--Brush ,Rectangle.While instantiate this delegate,there is only one parm--aGraphics.FillRectangle.I don't understand how this can work.

Thanks for everyone who can help.

Regards,
Sam





Re: Visual C# Language Delegate signature doesn't match but can compile?

Peter Ritchie

It helps when you provide the full source to an example.

I'm assuming that aGraphics is a System.Drawing.Graphics object, in which case, Graphics.FillRectangle has the same parameters and return value required for a method passed to the DrawShape constructor (void(Brush, Rectangle)). When you define a delegate like DrawShape(Brush, Rectangle) you're saying you can only instantiate that delegate with a method that has those parameters and return value.






Re: Visual C# Language Delegate signature doesn't match but can compile?

SamSam698

Thanks Peter.

I found I used an incorrect example.Please refer to below code:
//***********************************
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;

namespace EmployeeDelegate
{
delegate void ApplyRaiseDelegate<T>(T instance,Decimal percent);
public class Employee
{
private Decimal salary;

public Employee(Decimal salary)
{
this.salary = salary;
}
public decimal Salary
{
get
{
return salary;
}
}
public void ApplyRaiseOf(Decimal percent)
{
salary *= (1 + percent);
}
}
class Program
{
static void Main(string[] args)
{
List<Employee> employees = new List<Employee>();
employees.Add(new Employee(40000));
employees.Add(new Employee(65000));
employees.Add(new Employee(95000));

MethodInfo mi = typeof(Employee).GetMethod("ApplyRaiseOf",
BindingFlags.Instance |
BindingFlags.Public);
ApplyRaiseDelegate<Employee> applyRaise =
(ApplyRaiseDelegate<Employee>)Delegate.CreateDelegate(
typeof(ApplyRaiseDelegate<Employee>), mi);
foreach (Employee e in employees)
{
applyRaise(e, (Decimal)0.10);
Console.WriteLine(e.Salary);
}

}
}
}

//******************************************

Kindly notice the signature of delegate ApplyRaiseDelegate is void(T,Decimal).
But in the foreach loop,the instance of the delegate is
applyRaise(e, (Decimal)0.10) which actually invokes the method ApplyRaiseOf whose signature is :
void (Decimal)
What's happening here
Please help.Many many thanks.

Regards,
Sam








Re: Visual C# Language Delegate signature doesn't match but can compile?

Gregor Berginc

Sam,

you actually created an instance of ApplyRaiseDelegate<Employee>, so the first parameter of your delegate instantiation is not T but Employee (ApplyRaiseDelegate is declared as a generic delegate, where T is replaced with whatever type you put within <>).

best,





Re: Visual C# Language Delegate signature doesn't match but can compile?

Peter Ritchie

Now that's a completely different scenario.

What you're encountering is an overloaded ability of Delegate.CreateDelegate. In .NET 1.1 CreateDelegate only supported static members. In .NET 2.0 CreateDelegate is overloaded to support instance members if the delegate it's asked to create has a first parameter of same type as the instance you want to call it on. The method that the delegate is pointing to must have a signature with all the same parameters, except the first. What's really happening is you're creating a delegate to a hidden delegate and that delegate is calling the hidden delegate like this: hiddenDelegate(argument).

Unfortunately, the Delegate class isn't designed well for delegates to instance methods outside of compilers.

I'm assuming you're doing this to avoid having to create a delegate for each instance of Employee. It's not clear from you example why you're doing it that way, but you have all the information for "e.ApplyRaiseOf(10m)" instead of using delegates.






Re: Visual C# Language Delegate signature doesn't match but can compile?

SamSam698

Thanks Peter.Now I have a better feeling that the signature still matches just there is a hidden delegate works.

The code is from a web link.Actually I don't even understand why delegate should be used in such a complicated way.It is more complex than I can think how to use.I used to think C# is much easier to learn than C++,but it seems that I was wrong.I found C++ is easier to learn than C#.There is no such hidden things in C++.

Regards,
Sam





Re: Visual C# Language Delegate signature doesn't match but can compile?

.NETPhreak

Covariance + Contravariance + Generics at play here...

Lookup these three words in msdn, Sam to get a better idea. Events and delegates are one of the few 'tougher' topics to grasp in .NET. But with some working knowledge, you should be able to figure out that only sky is the limit. You may come across 'anonymous methods' while you research delegates: my advice to you is to avoid this topic until you completely understand delegates and events (especially the generic versions in .NET 2.0).