Generic delegate implementation question

  • Thread starter Thread starter Dave
  • Start date Start date
D

Dave

I've got these declarations:
public delegate void FormDisplayResultsDelegate<Type>(Type
displayResultsValue);
public FormDisplayResultsDelegate<string> displayMsgDelegate;

instantiation:
displayMsgDelegate = DisplayStatusMessage;

implementation:
public void DisplayStatusMessage(string statusMessage)
{
StatusTextBox.Text = statusMessage;
}

however, the following seems more proper to me and also works:
public void DisplayStatusMessage<Type>(Type statusMessage)
{
StatusTextBox.Text = statusMessage.ToString();
}

can anyone explain what's happening under the covers please?
(implicit casting i guess?...)

thanks, dave
 
Dave said:
I've got these declarations:
public delegate void FormDisplayResultsDelegate<Type>(Type
displayResultsValue);
public FormDisplayResultsDelegate<string> displayMsgDelegate;

instantiation:
displayMsgDelegate = DisplayStatusMessage;

implementation:
public void DisplayStatusMessage(string statusMessage)
{
StatusTextBox.Text = statusMessage;
}

however, the following seems more proper to me and also works:
public void DisplayStatusMessage<Type>(Type statusMessage)
{
StatusTextBox.Text = statusMessage.ToString();
}

can anyone explain what's happening under the covers please?
(implicit casting i guess?...)

Can you post the code in which the second method declaration "works"?
How are you using the method? As an alternative to declaring the
delegate at all? Or are you somehow using an instance of the generic
method to initialize the delegate variable?

I can see why it would work in some cases but if you, for example, used
"int" instead of "string" as the Type parameter for the generic method,
it wouldn't. That is, you wouldn't be able to assign that concrete
instance of the generic method to the concrete "string"-based delegate type.

I'm not sure why the generic method seems more proper to you, but the
basic reason it works is that the method signature that results matches
the signature required by the delegate. A generic method can only be
used with a concrete instance of that method, and once you create that
concrete instance, it's just like any other method, with a signature
that looks just like any other method.

So as long as you create a concrete instance of your generic method that
has the same signature required by the delegate, you can use it.

However, that's not to say that's necessarily a useful way to use a
generic method. A generic method has the same basic purpose as generic
types; that is, it allows you to declare a method that can be used with
a wide variety of types without knowing the type in advance. However,
in your example, there's not necessarily anything about your method that
takes advantage of being generic.

Without knowing exactly what you're trying to do, it's hard to say which
is "better". If you really want a generic method to go along with the
generic delegate type, then I'd say the generic method is better. But
from only the code you posted, it's not really obvious why generics are
being used at all. And if generics are desirable, it may be that you
have a design where you need a specific implementation for each delegate
concrete instance and so making a new generic method for each different
type wouldn't make sense.

In other words, all possibilities are valid designs. But they
definitely don't do the same thing, so which one is best for your
purposes really depends on what you are trying to do.

Pete
 
Can you post the code in which the second method declaration "works"?
How are you using the method? As an alternative to declaring the
delegate at all? Or are you somehow using an instance of the generic
method to initialize the delegate variable?

I can see why it would work in some cases but if you, for example, used
"int" instead of "string" as the Type parameter for the generic method,
it wouldn't. That is, you wouldn't be able to assign that concrete
instance of the generic method to the concrete "string"-based delegate type.

I'm not sure why the generic method seems more proper to you, but the
basic reason it works is that the method signature that results matches
the signature required by the delegate. A generic method can only be
used with a concrete instance of that method, and once you create that
concrete instance, it's just like any other method, with a signature
that looks just like any other method.

So as long as you create a concrete instance of your generic method that
has the same signature required by the delegate, you can use it.

However, that's not to say that's necessarily a useful way to use a
generic method. A generic method has the same basic purpose as generic
types; that is, it allows you to declare a method that can be used with
a wide variety of types without knowing the type in advance. However,
in your example, there's not necessarily anything about your method that
takes advantage of being generic.

Without knowing exactly what you're trying to do, it's hard to say which
is "better". If you really want a generic method to go along with the
generic delegate type, then I'd say the generic method is better. But
from only the code you posted, it's not really obvious why generics are
being used at all. And if generics are desirable, it may be that you
have a design where you need a specific implementation for each delegate
concrete instance and so making a new generic method for each different
type wouldn't make sense.

In other words, all possibilities are valid designs. But they
definitely don't do the same thing, so which one is best for your
purposes really depends on what you are trying to do.

Pete- Hide quoted text -

- Show quoted text -

Here is more code showing more context. I'm using a generic delegate
declaration allowing for reuse / single declaration, as shown below..

So again I'm simply wondering why the non generic method
implementation (ProgressBarSetup()) works seemlessly? I assume there
is implicit casting going on but ...?

public delegate void FormDisplayResultsDelegate<Type>(Type
displayResultsValue); // generic single value delegate
public FormDisplayResultsDelegate<string> displayMsgDelegate;
public FormDisplayResultsDelegate<int> progressBarSetupMsgDelegate;
public FormDisplayResultsDelegate<int> concurrentRequestDelegate;
public FormDisplayResultsDelegate<int> outstandingRequestDelegate;
....

progressBarSetupMsgDelegate = ProgressBarSetup;
....

public void ProgressBarSetup(int outstandingConnAttemptsArg)
{
if (RequestAttemptProgressBar.InvokeRequired)
{

RequestAttemptProgressBar.BeginInvoke(progressBarSetupMsgDelegate, new
object[] { outstandingConnAttemptsArg });
}
else
{
RequestAttemptProgressBar.Refresh();
RequestAttemptProgressBar.Minimum = 1;
RequestAttemptProgressBar.Value = 1;
RequestAttemptProgressBar.Step = 1;
if (outstandingConnAttemptsArg > 0)
{
RequestAttemptProgressBar.Maximum =
outstandingConnAttemptsArg;
}
else
{
RequestAttemptProgressBar.Maximum = 2;
}
RequestAttemptProgressBar.Visible = true;
}
}
 
Dave said:
[...]
Here is more code showing more context. I'm using a generic delegate
declaration allowing for reuse / single declaration, as shown below..

Sorry, but yhe code you posted fails to meet both the
"concise-but-complete" standard that is necessary for useful code
samples, as well as doesn't really provide (at least for me) insight as
to why a generic method would be desirable in your case.

Heck, the code you posted doesn't even use a generic method.
So again I'm simply wondering why the non generic method
implementation (ProgressBarSetup()) works seemlessly? I assume there
is implicit casting going on but ...?

Since you didn't post any code using the generic method, it's hard to
answer the question of what's going on in your case. However, I doubt
there's any implicit casting going on.

If you are using the generic method successfully, it is most likely
because the resulting method signature is exactly the signature required
by the delegate to which you assign the method instance. No casting
would be required, as the types would already match.

Pete
 
Dave said:
[...]
Here is more code showing more context. I'm using a generic delegate
declaration allowing for reuse / single declaration, as shown below..

Sorry, but yhe code you posted fails to meet both the
"concise-but-complete" standard that is necessary for useful code
samples, as well as doesn't really provide (at least for me) insight as
to why a generic method would be desirable in your case.

Heck, the code you posted doesn't even use a generic method.
So again I'm simply wondering why the non generic method
implementation (ProgressBarSetup()) works seemlessly? I assume there
is implicit casting going on but ...?

Since you didn't post any code using the generic method, it's hard to
answer the question of what's going on in your case. However, I doubt
there's any implicit casting going on.

If you are using the generic method successfully, it is most likely
because the resulting method signature is exactly the signature required
by the delegate to which you assign the method instance. No casting
would be required, as the types would already match.

Pete

I'm not looking to use a generic method, only wondering why the non
generic method works / compiles seemlessly. i'm fine using the non-
generic method.

I only wanted the generic declaration to avoid multiple / similar non-
generic delegate declarations.

i did not include the call as it didn't lend much to the discussion
but here it is (as called from another thread / object):
parentObj.ParentFormObj.ProgressBarSetup(0);

thanks for your efforts, no further info needed, dave
 
Dave said:
I've got these declarations:
public delegate void FormDisplayResultsDelegate<Type>(Type
displayResultsValue);
public FormDisplayResultsDelegate<string> displayMsgDelegate;

instantiation:
displayMsgDelegate = DisplayStatusMessage;

implementation:
public void DisplayStatusMessage(string statusMessage)
{
StatusTextBox.Text = statusMessage;
}

however, the following seems more proper to me and also works:
public void DisplayStatusMessage<Type>(Type statusMessage)
{
StatusTextBox.Text = statusMessage.ToString();
}

can anyone explain what's happening under the covers please?
(implicit casting i guess?...)

Eek - I would *strongly* advise against using an existing type name
("Type") as the name of a generic parameter. Let's rewrite that as:

public delegate void FormDisplayResultsDelegate<T>
(T displayResultsValue)

That's a lot easier to understand - no confusion with
System.Reflection.Type.

Now, as for why you can do:

displayMsgDelegate = DisplayStatusMessage;

with both the non-generic and generic versions - it's type inferencing
and an implicit conversion from method-group to a particular delegate
type. Method groups containing a method with a signature of

void Foo(string x)
and
void Foo<T>(T x)

can both be implicitly converted to FormDisplayResultsDelegate<string>.
 
Eek - I would *strongly* advise against using an existing type name
("Type") as the name of a generic parameter. Let's rewrite that as:

public delegate void FormDisplayResultsDelegate<T>
(T displayResultsValue)

That's a lot easier to understand - no confusion with
System.Reflection.Type.

Now, as for why you can do:

displayMsgDelegate = DisplayStatusMessage;

with both the non-generic and generic versions - it's type inferencing
and an implicit conversion from method-group to a particular delegate
type. Method groups containing a method with a signature of

void Foo(string x)
and
void Foo<T>(T x)

can both be implicitly converted to FormDisplayResultsDelegate<string>.

--
Jon Skeet - <[email protected]>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too- Hide quoted text -

- Show quoted text -

oh good that's what i sorta thought - great to get more precisely
explained!

thanks, dave
 
Dave said:
I'm not looking to use a generic method, only wondering why the non
generic method works / compiles seemlessly. i'm fine using the non-
generic method.

Ah. Well, that was not at all clear from your post. If anything it
seemed more like you were wondering why the generic method works.

The answer is still basically the same though. The non-generic method
works because its signature matches the concrete delegate signature
exactly. That is, once you apply a specific type to the generic
delegate type, you get a signature that's the same as the non-generic
method.

There's no casting involved. You are dealing with types that already match.

Pete
 
Back
Top