473,748 Members | 2,281 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(Point3 D 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(Point3 D pt) { _x = pt.X; _y = pt.Y; _z = pt.Z; }

public static implicit operator Vector3D(Point3 D 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 5666
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.co m>
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******** ********@TK2MSF TNGP05.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(Point3 D 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(Point3 D pt) { _x = pt.X; _y = pt.Y; _z = pt.Z; }

public static implicit operator Vector3D(Point3 D 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*********@nn owslpianmk.comw rote 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(Point3 D) 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.nos pamwrote:
>[...]
* 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(Point3 D 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.InvalidC astException 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.co m>
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
3095
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, piece types, squares, etc.). To accomplish this, I used implicit conversions. For instance, a color used to be: typedef int Color; // and a few constants... Now a color is (paraphrased):
9
8516
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
7621
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 Test. I expected the same error from the following line, but it compiles fine. The double is silently truncated to an int and then fed in to the implicit conversion operator. Why does this happen? Is there any way that I can keep the implicit...
9
2085
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 emulate the pattern im trying to follow in an existing project. These are my steps: 1) I have a method "printMe" existing in the application which originally used to take in a string. This method is static and sits in the Driver
36
3632
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 in a C# program but not VB? -- Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/ "Programming is an art form that fights back"
3
8120
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, because i need to talk to an Ftp server that supports only the explicit connections. changing the server is out of question. and i need ssl to keep login and password secure. to make things worse i can only log in using ssl. then i need to use Clear...
17
2511
by: arindam.mukerjee | last post by:
I was running code like: #include <stdio.h> int main() { printf("%f\n", 9/5); return 0; }
18
2387
by: Tony | last post by:
class Interface { public: virtual void DoItNow()=0; }; class A: public Interface { public: void DoItNow(); // satisfies interface explicitly
1
1841
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 it's Selected value like this : SelectedValue='<%# Bind("TaxCondition") %>'. In this case, TaxCondition is an int, and the conversion from int to string and string to int is made automatically.
0
8995
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
8832
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
9558
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...
1
9331
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
9253
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6077
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
4608
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2791
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.