473,399 Members | 4,177 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

implicit upcast possible?

Hi, Is it possible to define a implicit operator from base to derived
types in C#?
I have a Point class and would like to derive a Vector class from it and
add a couple new vector related functions, like Normalize(). The problem
is Vector cannot use any of the Point operator overloads with a compile
time error that there is no implicit conversion from Point to Vector. I
tried adding an implicit operator to Vector:

public static implicit operator Vector3D(Point3D a)
{ return new Vector3D(pt); }

But that doesn't compile either resulting error CS0553. Here is some
relevant code snips:

public class Point3D
{
protected double _x, _y, _z;

public static Point3D operator *(Point3D a, double b)
{
return new Point3D(a.X * b, a.Y * b, a.Z * b);
}
}

public class Vector3D : Point3D
{
public Vector3D(Point3D pt) { _x = pt.X; _y = pt.Y; _z = pt.Z; }

public static implicit operator Vector3D(Point3D a)
{ return new Vector3D(pt); }
}

If it allows and explicit upcast conversion, I don't understand why it
would not allow me to define an implicit operator, being the author of
the classes I know that it is safe to upcast implicitly.

Thanks.
Dec 5 '07 #1
8 5628
On Wed, 05 Dec 2007 14:38:54 -0800, jonpb <no****@nospam.comwrote:
[...]
If it allows and explicit upcast conversion, I don't understand why it
would not allow me to define an implicit operator, being the author of
the classes I know that it is safe to upcast implicitly.
I'm sure someone more knowledgeable will provide a detailed answer. But a
couple of thoughts from the peanut gallery:

* How is an implicit upcast supposed to work, especially when defined
in the derived class? All the compiler knows is that you've got a
Point3D, and the implicit cast defined is not in that class. Never mind
the question of what the behavior should be given that multiple derived
types could exist and would not necessarily be known at the time the
upcasting code was compiled.

* As far as the specific problem goes, can't you just define a new
operator* in Vector3D that just uses the base class version, explicitly
casting back up to Vector3D for the result?

Pete
Dec 5 '07 #2
jonpb <no****@nospam.comwrote:
Hi, Is it possible to define a implicit operator from base to derived
types in C#?
No. From the spec, section 10.10.3 (unified C#3 spec)

<quote>
For a given source type S and target type T, if S or T are nullable
types, let S0 and T0 refer to their underlying types, otherwise S0 and
T0 are equal to S and T respectively. A class or struct is permitted to
declare a conversion from a source type S to a target type T only if
all of the following are true:
" S0 and T0 are different types.
" Either S0 or T0 is the class or struct type in which the operator
declaration takes place.
" Neither S0 nor T0 is an interface-type.
" Excluding user-defined conversions, a conversion does not exist
from S to T or from T to S.
</quote>

Note the last point.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 5 '07 #3

"jonpb" <no****@nospam.comwrote in message
news:uD****************@TK2MSFTNGP05.phx.gbl...
Hi, Is it possible to define a implicit operator from base to derived
types in C#?
I have a Point class and would like to derive a Vector class from it and
add a couple new vector related functions, like Normalize(). The problem
is Vector cannot use any of the Point operator overloads with a compile
time error that there is no implicit conversion from Point to Vector. I
tried adding an implicit operator to Vector:

public static implicit operator Vector3D(Point3D a)
{ return new Vector3D(pt); }

But that doesn't compile either resulting error CS0553. Here is some
relevant code snips:

public class Point3D
{
protected double _x, _y, _z;

public static Point3D operator *(Point3D a, double b)
{
return new Point3D(a.X * b, a.Y * b, a.Z * b);
}
}

public class Vector3D : Point3D
{
public Vector3D(Point3D pt) { _x = pt.X; _y = pt.Y; _z = pt.Z; }

public static implicit operator Vector3D(Point3D a)
{ return new Vector3D(pt); }
}

If it allows and explicit upcast conversion, I don't understand why it
would not allow me to define an implicit operator, being the author of the
classes I know that it is safe to upcast implicitly.
That's a downcast. MSDN gives the reason:

It is not possible to redefine a pre-defined conversion. Thus, conversion
operators are not allowed to convert from or to object because implicit and
explicit conversions already exist between object and all other types.
Likewise, neither the source nor the target types of a conversion can be a
base type of the other, since a conversion would then already exist.

http://msdn2.microsoft.com/en-us/library/aa664464.aspx

The existing conversion is a dynamic type check... which will fail.

Overload the functions as Peter suggests.
>
Thanks.

Dec 5 '07 #4

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Wed, 05 Dec 2007 14:38:54 -0800, jonpb <no****@nospam.comwrote:
>[...]
If it allows and explicit upcast conversion, I don't understand why it
would not allow me to define an implicit operator, being the author of
the classes I know that it is safe to upcast implicitly.

I'm sure someone more knowledgeable will provide a detailed answer. But a
couple of thoughts from the peanut gallery:

* How is an implicit upcast supposed to work, especially when defined
in the derived class? All the compiler knows is that you've got a
Point3D, and the implicit cast defined is not in that class. Never mind
the question of what the behavior should be given that multiple derived
types could exist and would not necessarily be known at the time the
upcasting code was compiled.

* As far as the specific problem goes, can't you just define a new
operator* in Vector3D that just uses the base class version, explicitly
casting back up to Vector3D for the result?
No, the explicit cast (downcast) will do a dynamic type check. Since the
runtime type is not Vector3D, it will fail with an exception.

Calling the Vector3D(Point3D) constructor is an option however.
>
Pete

Dec 5 '07 #5
On Wed, 05 Dec 2007 15:13:50 -0800, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>[...]
* As far as the specific problem goes, can't you just define a new
operator* in Vector3D that just uses the base class version, explicitly
casting back up to Vector3D for the result?

No, the explicit cast (downcast) will do a dynamic type check. Since the
runtime type is not Vector3D, it will fail with an exception.
Ah, right. I should have looked more closely at the operator definition
itself.

But as you say, using the constructor is an alternative to casting that
would actually work.

Pete
Dec 5 '07 #6
Ben Voigt [C++ MVP] wrote:
"jonpb" <no****@nospam.comwrote in message
>>
public static implicit operator Vector3D(Point3D a)
{ return new Vector3D(pt); }
That's a downcast. MSDN gives the reason:
No, it's an upcast going from base (Point3D) to derived (Vector3D).
On that point, the error message that VS2005 gives you is wrong also, as
it says, as you said, that it is downcast and is not required.
http://msdn2.microsoft.com/en-us/library/aa664464.aspx

The existing conversion is a dynamic type check... which will fail.
Ok, I must have eaten a bowl full of stupid today, because I really
don't get this. The spec is saying that a conversion "already exists" to
and from base and derived classes, and yet, in the case of base to
derived (upcast), the compiler can't find the implicit one and the
explicit one results in a runtime error.
>
Overload the functions as Peter suggests.
The whole point in deriving was not to have to do that. oh, well.
Dec 6 '07 #7
jonpb wrote:
Ok, I must have eaten a bowl full of stupid today, because I really
don't get this. The spec is saying that a conversion "already exists" to
and from base and derived classes, and yet, in the case of base to
derived (upcast), the compiler can't find the implicit one and the
explicit one results in a runtime error.
Sorry I should have continued that thought:

And on top of that, It won't let you define an implicit cast that you
know will be safe, because it thinks it is already defined, even though
it can't find it!

For what it's worth, I don't think upcasting implicitly or explicitly
should be allowed unless specifically defined by the author of the
objects. But, I do feel strongly that the ability to define these casts
would be very helpful.
Dec 6 '07 #8
jonpb <no****@nospam.comwrote:
That's a downcast. MSDN gives the reason:
No, it's an upcast going from base (Point3D) to derived (Vector3D).
On that point, the error message that VS2005 gives you is wrong also, as
it says, as you said, that it is downcast and is not required.
No - base to derived = downcast. Derived to base = upcast.
http://msdn2.microsoft.com/en-us/library/aa664464.aspx

The existing conversion is a dynamic type check... which will fail.
Ok, I must have eaten a bowl full of stupid today, because I really
don't get this. The spec is saying that a conversion "already exists" to
and from base and derived classes, and yet, in the case of base to
derived (upcast), the compiler can't find the implicit one and the
explicit one results in a runtime error.
There's an explicit conversion from an expression of type Base to
Derived - but it may fail at execution time. There's no implicit
conversion precisely because it may fail at execution time.

From the spec (section 6.2.4, unified C# 3 spec):

<quote>
The explicit reference conversions are:

....

" From any class-type S to any class-type T, provided S is a base
class of T.

....
The explicit reference conversions are those conversions between
reference-types that require run-time checks to ensure they are
correct.

For an explicit reference conversion to succeed at run-time, the value
of the source operand must be null, or the actual type of the object
referenced by the source operand must be a type that can be converted
to the destination type by an implicit reference conversion (§6.1.6).
If an explicit reference conversion fails, a
System.InvalidCastException is thrown.
</quote>

In other words, you can do:

Base b = new Derived();
Derived d = (Derived) b; // Works

But you can't do:

Base b = new Base();
Derived d = (Derived) b; // Fails

because in the latter case the object isn't *actually* an instance of
Derived.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Dec 6 '07 #9

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

Similar topics

2
by: Russell Reagan | last post by:
In a newer version of a chess program I am writing, I have created classes that are (more or less) drop in replacements for things that used to be plain old integer or enumerated variables (colors,...
9
by: Simon | last post by:
Hi All, Is it possible to disallow implicit casting for an operand of a function written in C? i.e. void foo(int a) {..} short b; foo(b) // error without explicit cast
11
by: Steve Gough | last post by:
Could anyone please help me to understand what is happening here? The commented line produces an error, which is what I expected given that there is no conversion defined from type double to type...
9
by: Girish | last post by:
Im trying to understand implicit type conversions from object -> string and vice versa. I have two classes, one Driver and one called StringWrapper. These are just test classes that try and...
36
by: Chad Z. Hower aka Kudzu | last post by:
I have an implicit conversion set up in an assembly from a Stream to something else. In C#, it works. In VB it does not. Does VB support implicit conversions? And if so any idea why it would work...
3
by: SharpCoderMP | last post by:
hi, i've found out here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=131195&SiteID=1 that FtpWebRequest does not support implicit connections. I have a serious problem with that,...
17
by: arindam.mukerjee | last post by:
I was running code like: #include <stdio.h> int main() { printf("%f\n", 9/5); return 0; }
18
by: Tony | last post by:
class Interface { public: virtual void DoItNow()=0; }; class A: public Interface { public: void DoItNow(); // satisfies interface explicitly
1
by: drop | last post by:
Hi all, I'd like to know if it's possible to declare an implicit type conversion for when I use declarative Synthax in html. For example, when I have the DropDownList, I can declatively set...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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...
0
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,...
0
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...

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.