473,699 Members | 2,417 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Covariance in delegates doesn't work with ValueType's?

Let me start with a quote from the C# Programmers Reference (where I
learned the cool word "covariance "):

"When a delegate method has a return type that is more derived than the
delegate signature, it is said to be covariant. Because the method's
return type is more specific than the delegate signature's return type,
it can be implicitly converted. The method is therefore acceptable for
use as a delegate."

It then goes on to give an archetypal example using Mammals and Dogs,
which is all well and good because both of those are reference types.
However, I'm working on a piece of code where I wanted to use a value
types for the return type from the delegate, and it just won't work.
Here's some sample code (adapted from the C# Programmers Reference
example actually):

public delegate object MyHandlerMethod ();

public static string MyFirstHandler( )
{
return null;
}

public static int MySecondHandler ()
{
return 1;
}

static void Main(string[] args)
{
MyHandlerMethod handler_1 = new MyHandlerMethod (MyFirstHandler );

// Covariance should allows this delegate, but it doesn't
// error CS0407: 'int MyFirstHandler( )' has the wrong return type
MyHandlerMethod handler_2 = new MyHandlerMethod (MySecondHandle r);
}

I was a bit surprised, since supposedly all value types (such as int)
derive from the same base, System.Object. Furthermore, even specifying
ValueType as the return from the delegate (and limiting its use to value
types such as MySecondHandler , of course) doesn't change anything. Is
there anyway to achieve covariance using ValueType's, or am I missing
something real obvious here?

-Aryeh Holzer
Nov 17 '05 #1
6 2138
Aryeh Holzer <ar**********@g mail.com> wrote:
Let me start with a quote from the C# Programmers Reference (where I
learned the cool word "covariance "):
<snip>
I was a bit surprised, since supposedly all value types (such as int)
derive from the same base, System.Object. Furthermore, even specifying
ValueType as the return from the delegate (and limiting its use to value
types such as MySecondHandler , of course) doesn't change anything. Is
there anyway to achieve covariance using ValueType's, or am I missing
something real obvious here?


I suspect the problem is that value types *don't* actually derive from
the same base class. Value types themselves don't derive from anything.
The boxed version of the value type is the one which derives from
ValueType.

Basically, covariance says, "It's okay, I know I can use the return
value appropriately" - but in the case of value types it can't, because
it's expecting a reference to come back, not an actual value. They
could probably wire it up so that it did the boxing, but I suspect they
haven't for the sake of simplicity. I agree it's a pain though.

You might want to raise this as a feature request on the feedback
centre at http://lab.msdn.microsoft.com/

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #2
Jon Skeet [C# MVP] wrote:
Aryeh Holzer <ar**********@g mail.com> wrote:
Let me start with a quote from the C# Programmers Reference (where I
learned the cool word "covariance "):

<snip>
I was a bit surprised, since supposedly all value types (such as int)
derive from the same base, System.Object. Furthermore, even specifying
ValueType as the return from the delegate (and limiting its use to value
types such as MySecondHandler , of course) doesn't change anything. Is
there anyway to achieve covariance using ValueType's, or am I missing
something real obvious here?

I suspect the problem is that value types *don't* actually derive from
the same base class. Value types themselves don't derive from anything.
The boxed version of the value type is the one which derives from
ValueType.

Basically, covariance says, "It's okay, I know I can use the return
value appropriately" - but in the case of value types it can't, because
it's expecting a reference to come back, not an actual value. They
could probably wire it up so that it did the boxing, but I suspect they
haven't for the sake of simplicity. I agree it's a pain though.

You might want to raise this as a feature request on the feedback
centre at http://lab.msdn.microsoft.com/


I'm sure you're right, although the documentation is very confusing,
then. The entries on "Structs", for instance, says "All value types in
C# inherently derive from System.ValueTyp e, which inherits from
System.Object. Value types can be converted to reference types by the
compiler in a process known as boxing." - which kind of implies that
the ValueType is not natively a reference, but must be converted into
one by boxing it.

Thanks for the pointer (ow) to the feedback center, I think I'll head
there now.
Nov 17 '05 #3
Aryeh Holzer <ar**********@g mail.com> wrote:
Let me start with a quote from the C# Programmers Reference (where I
learned the cool word "covariance "):
<snip>
I was a bit surprised, since supposedly all value types (such as int)
derive from the same base, System.Object. Furthermore, even specifying
ValueType as the return from the delegate (and limiting its use to value
types such as MySecondHandler , of course) doesn't change anything. Is
there anyway to achieve covariance using ValueType's, or am I missing
something real obvious here?


I suspect the problem is that value types *don't* actually derive from
the same base class. Value types themselves don't derive from anything.
The boxed version of the value type is the one which derives from
ValueType.

Basically, covariance says, "It's okay, I know I can use the return
value appropriately" - but in the case of value types it can't, because
it's expecting a reference to come back, not an actual value. They
could probably wire it up so that it did the boxing, but I suspect they
haven't for the sake of simplicity. I agree it's a pain though.

You might want to raise this as a feature request on the feedback
centre at http://lab.msdn.microsoft.com/

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #4
Jon Skeet [C# MVP] wrote:
Aryeh Holzer <ar**********@g mail.com> wrote:
Let me start with a quote from the C# Programmers Reference (where I
learned the cool word "covariance "):

<snip>
I was a bit surprised, since supposedly all value types (such as int)
derive from the same base, System.Object. Furthermore, even specifying
ValueType as the return from the delegate (and limiting its use to value
types such as MySecondHandler , of course) doesn't change anything. Is
there anyway to achieve covariance using ValueType's, or am I missing
something real obvious here?

I suspect the problem is that value types *don't* actually derive from
the same base class. Value types themselves don't derive from anything.
The boxed version of the value type is the one which derives from
ValueType.

Basically, covariance says, "It's okay, I know I can use the return
value appropriately" - but in the case of value types it can't, because
it's expecting a reference to come back, not an actual value. They
could probably wire it up so that it did the boxing, but I suspect they
haven't for the sake of simplicity. I agree it's a pain though.

You might want to raise this as a feature request on the feedback
centre at http://lab.msdn.microsoft.com/


I'm sure you're right, although the documentation is very confusing,
then. The entries on "Structs", for instance, says "All value types in
C# inherently derive from System.ValueTyp e, which inherits from
System.Object. Value types can be converted to reference types by the
compiler in a process known as boxing." - which kind of implies that
the ValueType is not natively a reference, but must be converted into
one by boxing it.

Thanks for the pointer (ow) to the feedback center, I think I'll head
there now.
Nov 17 '05 #5
Aryeh Holzer <ar**********@g mail.com> wrote:
I'm sure you're right, although the documentation is very confusing,
then. The entries on "Structs", for instance, says "All value types in
C# inherently derive from System.ValueTyp e, which inherits from
System.Object. Value types can be converted to reference types by the
compiler in a process known as boxing." - which kind of implies that
the ValueType is not natively a reference, but must be converted into
one by boxing it.

Thanks for the pointer (ow) to the feedback center, I think I'll head
there now.


Yes, the value type system *is* very confusing, unfortunately. The ECMA
CLI spec is the clearest here:

<quote>
Not all types defined by a class definition are object types (see
clause 8.2.3); in particular, value types are not object types but they
are defined using a class definition. A class definition for a value
type defines both the (unboxed) value type and the associated boxed
type (see clause 8.2.4). The members of the class definition define the
representation of both: 1. When a non-static method (i.e. an instance
or virtual method) is called on the value type its this pointer is a
managed reference to the instance, whereas when the method is called on
the associated boxed type the this pointer is an object reference.
Instance methods on value types receive a this pointer that is a
managed pointer to the unboxed type whereas virtual methods (including
those on interfaces implemented by the value type) receive an instance
of the boxed type.

1. Value types do not support interface contracts, but their associated
boxed types do.

2. A value type does not inherit; rather the base type specified in the
class definition defines the base type of the boxed type.
</quote>

and

<quote>
Value Types, in their unboxed form, do not inherit from any type. Boxed
value types shall inherit directly from System.ValueTyp e unless they
are enumerations, in which case they shall inherit from System.Enum.
Boxed value types shall be sealed.
</quote>
Still not as clear as it might be - and not helped by typeof(int), for
example, claiming to be a value type but also claiming to derive from
ValueType, etc...

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #6
Aryeh Holzer <ar**********@g mail.com> wrote:
I'm sure you're right, although the documentation is very confusing,
then. The entries on "Structs", for instance, says "All value types in
C# inherently derive from System.ValueTyp e, which inherits from
System.Object. Value types can be converted to reference types by the
compiler in a process known as boxing." - which kind of implies that
the ValueType is not natively a reference, but must be converted into
one by boxing it.

Thanks for the pointer (ow) to the feedback center, I think I'll head
there now.


Yes, the value type system *is* very confusing, unfortunately. The ECMA
CLI spec is the clearest here:

<quote>
Not all types defined by a class definition are object types (see
clause 8.2.3); in particular, value types are not object types but they
are defined using a class definition. A class definition for a value
type defines both the (unboxed) value type and the associated boxed
type (see clause 8.2.4). The members of the class definition define the
representation of both: 1. When a non-static method (i.e. an instance
or virtual method) is called on the value type its this pointer is a
managed reference to the instance, whereas when the method is called on
the associated boxed type the this pointer is an object reference.
Instance methods on value types receive a this pointer that is a
managed pointer to the unboxed type whereas virtual methods (including
those on interfaces implemented by the value type) receive an instance
of the boxed type.

1. Value types do not support interface contracts, but their associated
boxed types do.

2. A value type does not inherit; rather the base type specified in the
class definition defines the base type of the boxed type.
</quote>

and

<quote>
Value Types, in their unboxed form, do not inherit from any type. Boxed
value types shall inherit directly from System.ValueTyp e unless they
are enumerations, in which case they shall inherit from System.Enum.
Boxed value types shall be sealed.
</quote>
Still not as clear as it might be - and not helped by typeof(int), for
example, claiming to be a value type but also claiming to derive from
ValueType, etc...

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
3079
by: Lore Leuneog | last post by:
Hi. You can add new delegates for an event with += and you can remove delegates from an event by using: -= but is there a way (method) to list all delegates added to one event??? Sincerely Greetings Lore
10
2002
by: Brad | last post by:
Question for all: Would one consider this a loophole in .net with respect to nested (inner) classes? 1) Create outer class Foo and create a nested class Yin (inside Foo's class definition ofcourse). 2) Let Foo have non-static protected (or public) method Bar() and Yin have a non-static method called Yang(). 4) Add a member object to Foo of Class Yin called yinObj.
6
2289
by: Joanna Carter \(TeamB\) | last post by:
Hi folks I have a Generic Value Type and I want to detect when the internal value changes. /////////////////////////////// public delegate void ValueTypeValidationHandler<T>(T oldValue, T newValue); public struct TestType<T> {
0
278
by: Aryeh Holzer | last post by:
Let me start with a quote from the C# Programmers Reference (where I learned the cool word "covariance"): "When a delegate method has a return type that is more derived than the delegate signature, it is said to be covariant. Because the method's return type is more specific than the delegate signature's return type, it can be implicitly converted. The method is therefore acceptable for use as a delegate." It then goes on to give an...
14
3254
by: Lior Amar | last post by:
Quick question about threads and delegates. I have the following scenario Thread A (CLASSA) spawns Thread B (CLASSB) and passes it a DelegateA to a callback Thread B Invokes a DelegateB asynchronously (could be a timer but then we get Thread C) Upon completion of DelegateB, Thread B would like to callback ThreadA using DelegateA but as we all know the call to DelegateA is running in ThreadB. Is
5
4393
by: renjini | last post by:
I am a starter in C# ... I will present my problem : I am wrapping a C dll in C#. The C dll exports a function which takes a structure MYSTRUCT holding 2 function pointers(callback functions). struct MYSTRUCT { ontest1 t1;
1
3003
by: =?Utf-8?B?aGVyYmVydA==?= | last post by:
Jon Skeet wrote in the .NET general newsgroup 11/17/2005: "The difference between Invoke and DynamicInvoke is that the parameters to Invoke depend on the delegate itself - the method has the same signature as the delegate. DynamicInvoke has a "fixed" signature, and it dynamically calls Invoke with the appropriate parameters." So far I have seen DynamicInvoke only used in conjunction with generics event arguments. Is there any other...
5
2399
by: raylopez99 | last post by:
I understand delegates (static and non-static) and I agree they are very useful, and that the "Forms" used in the Windows .NET API could not work without them. That said, I'm curious as to how many heavy duty pro programmers in this newsgroup have actually used a delegate in their code, say in the last year of coding. By "use" I mean constructed a delegate and using it in an Event Source class and an Event Receiver class. Interfaces...
7
3418
by: Siegfried Heintze | last post by:
I'm studying the book "Microsoft Visual Basic.NET Language Reference" and I would like some clarify the difference between events and delegates. On page 156 I see a WinForms example of timer that uses the "WithEvents" and events. There is another example on page 124 that shows how to use delegates to sort an array. I don't understand the difference between events and delegates. Are they redundant features? How do I decide which to use? ...
0
8685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8613
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9172
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9032
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8908
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7745
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6532
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5869
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.