C# handing over delegates

  • Thread starter Thread starter schneider
  • Start date Start date
S

schneider

Hi all,

class A contains a function "test". the delegate instance in class B
is set to a.test. Now, I want to hand over this delegate from class B
to class C. How can I accomplish this? When I try, the compiler says
CS0029: Cannot implicitly convert type 'B.the_del' to 'C.the_del'.
Here's the code:

class A
{
B b;
public A()
{
b = new B();
b.the_del = this.test; // works fine
}

public void test(int i)
{
}
}

class B
{
C c;
public B()
{
c = new C();
c.the_del = this.the_del; // CS0029
}
public delegate void testDel(int i);
public testDel the_del;
}

class C
{
public delegate void testDel(int i);
public testDel the_del;
}

Thanks in advance.

Cheers, Hannes
 
class A contains a function "test". the delegate instance in class B
is set to a.test. Now, I want to hand over this delegate from class B
to class C. How can I accomplish this? When I try, the compiler says
CS0029: Cannot implicitly convert type 'B.the_del' to 'C.the_del'.
Here's the code:

<snip>

The problem is that you've declared two different testDel delegate
types. Declare the delegate in just one place, and it should be fine.

Don't forget that you can declare a delegate type directly inside a
namespace, just like any other type - it doesn't have to be nested in
a class.

Jon
 
Hi all,

class A contains a function "test". the delegate instance in class B
is set to a.test. Now, I want to hand over this delegate from class B
to class C. How can I accomplish this? When I try, the compiler says
CS0029: Cannot implicitly convert type 'B.the_del' to 'C.the_del'.
Here's the code:

class A
{
B b;
public A()
{
b = new B();
b.the_del = this.test; // works fine
}

public void test(int i)
{
}
}

class B
{
C c;
public B()
{
c = new C();
c.the_del = this.the_del; // CS0029
}
public delegate void testDel(int i);
public testDel the_del;
}

class C
{
public delegate void testDel(int i);
public testDel the_del;
}

Thanks in advance.

Cheers, Hannes
 
Hannes,

Although testDel 'looks' the same in both B and C, it is 2 different
types

B.testDel and C.testDel

and the compiler does not know how to assign one to the other

The simplest solution is to refactor the delegate definition out of
the classes, giving

class B {
C c;
public B() {
c = new C();
c.the_del = this.the_del; // CS0029
}

public testDel the_del;
}

class C {

public testDel the_del;
}

// TestDel is now part of the same namespace as B & C and can be
accessed by either.
public delegate void TestDel(int i);



hth,
Alan.
 
Hannes,

Although testDel 'looks' the same in both B and C, it is 2 different
types

B.testDel and C.testDel

and the compiler does not know how to assign one to the other

The simplest solution is to refactor the delegate definition out of
the classes, giving

class B {
C c;
public B() {
c = new C();
c.the_del = this.the_del; // CS0029
}

public testDel the_del;
}

class C {

public testDel the_del;
}

// TestDel is now part of the same namespace as B & C and can be
accessed by either.
public delegate void TestDel(int i);

hth,
Alan.

Ah, I see. This looks very promising. Thank you very much, Alan and
Jon.

Hannes.
 
Hi all,

class A contains a function "test". the delegate instance in class B
is set to a.test. Now, I want to hand over this delegate from class B
to class C. How can I accomplish this? When I try, the compiler says
CS0029: Cannot implicitly convert type 'B.the_del' to 'C.the_del'.

That's because the two types are different. It's just like (I think) if
you had other types declared within the different classes and tried to
assign one to the other. For example:

class B
{
class B1
{
}
}

class C
{
class C1
{
}
}

You would not be allowed to write this code:

C1 c1 = new B1();

And for good reason too. :) I realize that in the delegate case, you
could argue that the basic signature of the two delegates is exactly the
same, but a) I'm not entirely sure that "under the hood" it really is, and
b) it seems to me that for strictest, most-safe type-safeness it's better
for the compiler to not treat delegates different than other types in this
respect (especially since you could in theory argue that two classes that
are identical should then also be interchangeable).

I'm no expert in the use of delegates, but it seems to me that you've got
a couple of ways around this:

1) Define the delegate outside of the two classes that must share, and
have them both use the same type. This may make more sense anyway,
assuming the two classes really are sharing the same delegates, since that
way you only have to maintain one delegate type declaration and of course
you can easily assign instances from one class to another.

2) Wrap the delegate in a method that redirects the call. That is:

class A
{
public delegate void testDel(int i);
public testDel the_del;
private B b;

private void _RedirectDelegate(int i)
{
the_del(i);
}

public A()
{
b = new B();
b.the_del = _RedirectDelegate;
}
}

class B
{
public delegate void testDel(int i);
public testDel the_del;
}

This second solution would retain the same basic design you've got, while
providing the functionality you desire. I don't find it particular
elegant, but if the two classes are actually wholly independent of each
other and there's no practical way to share a single delegate type
declaration between the two, it may be the only way to go.

(It should go without saying that the above code is just for
illustration...it obviously has the bare minimum required to demonstrate
what I'm talking about, and doesn't even include any error checking).

For all I know, there's a way to extract the actual function from a
delegate (maybe with Reflection?) and create a new delegate instance that
you can assign to the second class using the same function. But if there
is, I don't know how to do it. :)

Hope that helps.

Pete
 
That's because the two types are different. It's just like (I think) if
you had other types declared within the different classes and tried to
assign one to the other. For example:

class B
{
class B1
{
}
}

class C
{
class C1
{
}
}

You would not be allowed to write this code:

C1 c1 = new B1();

And for good reason too. :) I realize that in the delegate case, you
could argue that the basic signature of the two delegates is exactly the
same, but a) I'm not entirely sure that "under the hood" it really is, and
b) it seems to me that for strictest, most-safe type-safeness it's better
for the compiler to not treat delegates different than other types in this
respect (especially since you could in theory argue that two classes that
are identical should then also be interchangeable).

I'm no expert in the use of delegates, but it seems to me that you've got
a couple of ways around this:

1) Define the delegate outside of the two classes that must share, and
have them both use the same type. This may make more sense anyway,
assuming the two classes really are sharing the same delegates, since that
way you only have to maintain one delegate type declaration and of course
you can easily assign instances from one class to another.

2) Wrap the delegate in a method that redirects the call. That is:

class A
{
public delegate void testDel(int i);
public testDel the_del;
private B b;

private void _RedirectDelegate(int i)
{
the_del(i);
}

public A()
{
b = new B();
b.the_del = _RedirectDelegate;
}
}

class B
{
public delegate void testDel(int i);
public testDel the_del;
}

This second solution would retain the same basic design you've got, while
providing the functionality you desire. I don't find it particular
elegant, but if the two classes are actually wholly independent of each
other and there's no practical way to share a single delegate type
declaration between the two, it may be the only way to go.

(It should go without saying that the above code is just for
illustration...it obviously has the bare minimum required to demonstrate
what I'm talking about, and doesn't even include any error checking).

For all I know, there's a way to extract the actual function from a
delegate (maybe with Reflection?) and create a new delegate instance that
you can assign to the second class using the same function. But if there
is, I don't know how to do it. :)

Hope that helps.

Pete

Thank you very much, Pete.
 

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

Back
Top