Are delegates true type safe?

  • Thread starter karthick.ramachandran
  • Start date
K

karthick.ramachandran

Hi,

I was just reading this article

http://www.netobjectives.com/resources/downloads/Best_Practices_CSharp_Delegates.pdf

In which the author had mentioned

<quote>
Delegates would appear to be type safe. The compiler will not allow you
to instantiate a delegate by handing it a method with the wrong
signature, and so the user of the delegate can be confident that the
method is callable with the parameters
it expects, and will return the type it expects.

However, this is not true type safety. The signature-checking is the
only checking done by the compiler. If two delegate types are declared
with the same signature, one can be substituted for the other, and the
compiler will not care.

class Soldier
{
// Delegate type declared within a class, so outside entities will
// refer to it as type Soldier.Fireable
public delegate void Fireable();
// Class Soldier has a member of this type
Soldier.Fireable myWeapon;
// When you arm a Soldier you give it a delegate reference
// of type Soldier.Fireable
public void arm(Soldier.Fireable aWeapon) {
myWeapon = aWeapon;
}
// When you tell the soldier to fight, he uses the Soldier.Fireable
// delegate he holds a reference to
public void fight(){
myWeapon()
}
}
class Payroll
{
// This delegate has the same signature as Soldier.Fireable, but it
is
// a different type, being declared within Payroll. It's type is
// Payroll.Fireable
public delegate void Fireable();
}
The point of concern for us is that it turns out that the arm() method
in Soldier, which is declared as accepting a parameter of type
Soldier.Fireable() will, in fact, take a reference to
Payroll.Fireable(). Similarly, the fight() method will happily use it,
even though it is the wrong type.

</quote>

I tried the same program and tired to pass the delegate of
Payroll.Fireable type to the arm() method of Soldier class. Infact I
was not able to pass the type. Compiler gave me an error saying that it
cannot convert Payroll.Fireable to Solder.Fireable.

Am I missing out on something here? Or is the authors claim wrong?
Ideally I will think that I am not getting the point author is trying
to make.

It will be great if somebody can throw some light on this!!

Thanks!
- R Karthick
 
O

Oliver Sturm

(e-mail address removed) wrote:

I tried the same program and tired to pass the delegate of
Payroll.Fireable type to the arm() method of Soldier class. Infact I
was not able to pass the type. Compiler gave me an error saying that it
cannot convert Payroll.Fireable to Solder.Fireable.

Am I missing out on something here? Or is the authors claim wrong?
Ideally I will think that I am not getting the point author is trying
to make.

It will be great if somebody can throw some light on this!!

I can only imagine what the author meant is that you can use a method with
a totally different purpose to pass it to the constructor of the delegate.
To call the arm() method, you need to construct a delegate of type
Soldier.Fireable. But you could pass a totally different method - for
example, somewhere in your accounting class:

...
Soldier soldier = new Soldier();
soldier.arm(new Soldier.Fireable(calculateAccounts));
...

This would result in a soldier who would, when trying to fight, calculate
your accounts instead - might be a good thing if you ask me :)

Seriously, there are two things I can say about this:

1. I don't think there's a way to prevent a programmer who uses extensibility features implemented in someone else's code from plugging in code that might not do what the original author intended that code to do. The plugable code in the soldier's interface has the purpose of making the soldier extensible - the author of the soldier doesn't have control over the exact nature of the extensions that somebody else creates.

2. The good side of this is the great flexibility, and that's why I would certainly call this a feature instead of a glitch in type safety. This doesn't have anything to do with type safety, anyway - all the types we have here are perfectly safe. The author has found that he can't depend on the fact that the delegate that is used to arm the soldier actually fires a weapon. True, but nothing to do with type safety.


Oliver Sturm
 
C

Christof Nordiek

Hi,

I was just reading this article

http://www.netobjectives.com/resources/downloads/Best_Practices_CSharp_Delegates.pdf

In which the author had mentioned

<quote>
Delegates would appear to be type safe. The compiler will not allow you
to instantiate a delegate by handing it a method with the wrong
signature, and so the user of the delegate can be confident that the
method is callable with the parameters
it expects, and will return the type it expects.

However, this is not true type safety. The signature-checking is the
only checking done by the compiler. If two delegate types are declared
with the same signature, one can be substituted for the other, and the
compiler will not care.

class Soldier
{
// Delegate type declared within a class, so outside entities will
// refer to it as type Soldier.Fireable
public delegate void Fireable();
// Class Soldier has a member of this type
Soldier.Fireable myWeapon;
// When you arm a Soldier you give it a delegate reference
// of type Soldier.Fireable
public void arm(Soldier.Fireable aWeapon) {
myWeapon = aWeapon;
}
// When you tell the soldier to fight, he uses the Soldier.Fireable
// delegate he holds a reference to
public void fight(){
myWeapon()
}
}
class Payroll
{
// This delegate has the same signature as Soldier.Fireable, but it
is
// a different type, being declared within Payroll. It's type is
// Payroll.Fireable
public delegate void Fireable();
}
The point of concern for us is that it turns out that the arm() method
in Soldier, which is declared as accepting a parameter of type
Soldier.Fireable() will, in fact, take a reference to
Payroll.Fireable(). Similarly, the fight() method will happily use it,
even though it is the wrong type.

</quote>

I tried the same program and tired to pass the delegate of
Payroll.Fireable type to the arm() method of Soldier class. Infact I
was not able to pass the type. Compiler gave me an error saying that it
cannot convert Payroll.Fireable to Solder.Fireable.

Am I missing out on something here? Or is the authors claim wrong?
Ideally I will think that I am not getting the point author is trying
to make.

It will be great if somebody can throw some light on this!!

Thanks!
- R Karthick
Hi,

as far as i can see the author is wrong in two poinst.

1. A Delegate of type Payroll.Fireable can not be cast to Soldier.Fireable
(as of C#1.0)
2. Even if it was possible, it would remain typesafe. It would still not be
possible to asign an
unapropriate value to a variable.
It would be similar to int and char wich can be cast one to another. Or like
to Enumtypes with the same
underlying type.
 
J

Jon Skeet [C# MVP]

I was just reading this article

http://www.netobjectives.com/resources/downloads/Best_Practices_CSharp_Delegates.pdf

In which the author had mentioned

I tried the same program and tired to pass the delegate of
Payroll.Fireable type to the arm() method of Soldier class. Infact I
was not able to pass the type. Compiler gave me an error saying that it
cannot convert Payroll.Fireable to Solder.Fireable.

Am I missing out on something here? Or is the authors claim wrong?
Ideally I will think that I am not getting the point author is trying
to make.

The author is just plain wrong. Delegates *are* type-safe. My guess is
that he had a bug in some code he wrote at some point, and came to the
wrong conclusion.

(I must admit, as soon as I see code which not only ignores the normal
..NET naming conventions but also doesn't even stick to its own
conventions, I become wary...)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top