472,989 Members | 3,077 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Implicit conversion

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 conversion from int but guarantee a
compiler error if an attempt is made to cast from double?

class Test
{
public static implicit operator Test(int x)
{
return new Test();
}
}

class Driver
{
public static void Main()
{
//Test y = 4.5; // error
Test x = (Test)4.5; // this compiles
}
}

Many thanks

Steve Gough
Nov 15 '05 #1
11 7530
"Steve Gough" <st*************@hotmail.com> wrote in message
news:4a**************************@posting.google.c om...
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 conversion from int but guarantee a
compiler error if an attempt is made to cast from double?

class Test
{
public static implicit operator Test(int x)
{
return new Test();
}
}

class Driver
{
public static void Main()
{
//Test y = 4.5; // error
Test x = (Test)4.5; // this compiles
}
}

Hi Steve,

First, consider that there are implicit conversions and explicit
conversions. Implicit happens when there is no loss of information or an
exception can't be thrown. For example, and implicit conversion exists from
int to double because the value copied is preserved, but there is no
implicit conversion from double to int because you would loose precision.
This is why explicit conversions exist. They force you to say that if I
cast this double (4.5) to an int, I know that I am going to loose precision
(4).

When doing a conversion, C# looks for an operator that will allow it to
convert from the source type to a target type. It will first look to see if
there is an exact match of the source and target types. In your case, there
is not an exact match because 4.5 is a double and your conversion operator
expects an int. So, the next thing C# will do is see if there is a
conversion from the source type (double) to a type in any of the available
conversion operators (int).

In your first example (the one with the error), you are performing an
implicit conversion (no cast). So, C# is looking for an available
conversion operator in Test that will allow you to perform the implicit
conversion that you asked for. The only available conversion is for an int.
Since there is no implicit conversion from double to int, you get a compile
time error. This is as it should be.

Your second example succeeds because you specified (with the cast) that you
want to perform an explicit conversion. Since there is an explicit
conversion from double to int, C# will match your conversion operator in
Test. The conversion from double to int will occur, which truncates your
precision. Then the conversion operator on Test will execute. Since you
specified an explicit conversion, C# interpreted it as something you wanted
to do, regardless of the result.

Joe
--
http://www.csharp-station.com
Nov 15 '05 #2
I'm sorry, but this just makes me absolutely NUTS!
implicit conversion from double to int because you would <loose> precision. cast this double (4.5) to an int, I know that I am going to <loose>

precision

Please, everyone, look at this:

lose: (looz), to be unsuccessful in retaining possession of, mislay

loose: (loos), not fastened, detached, etc.

As in: Don't lose your virginity to a loose woman.

That really drives me crazy above all other grammatical errors!
Nov 15 '05 #3
Thank you for that correction. I really must refrain from being loose with
my grammar. Otherwise it would cause some people to get uptight. ;)

Joe
--
http://www.csharp-station.com

"GMorris" <gw*******@hotpop.com> wrote in message
news:OA**************@TK2MSFTNGP10.phx.gbl...
I'm sorry, but this just makes me absolutely NUTS!
implicit conversion from double to int because you would <loose>

precision.
cast this double (4.5) to an int, I know that I am going to <loose>

precision

Please, everyone, look at this:

lose: (looz), to be unsuccessful in retaining possession of, mislay

loose: (loos), not fastened, detached, etc.

As in: Don't lose your virginity to a loose woman.

That really drives me crazy above all other grammatical errors!

Nov 15 '05 #4
It's not just you, I see this constantly and it throws me for a loop
every time. I'm starting to get used to it, but I still have to stop and
re-read sentences that use loose for lose. Sometimes I just can't
stand it anymore and say something, hoping that others who make
the same error will see it and think about it. Maybe...

Sorry.

"Joe Mayo" <jm***@nospamAtCSharpDashStation.com> wrote in message
news:#E**************@TK2MSFTNGP10.phx.gbl...
Thank you for that correction. I really must refrain from being loose with my grammar. Otherwise it would cause some people to get uptight. ;)

Joe
--
http://www.csharp-station.com

"GMorris" <gw*******@hotpop.com> wrote in message
news:OA**************@TK2MSFTNGP10.phx.gbl...
I'm sorry, but this just makes me absolutely NUTS!
implicit conversion from double to int because you would <loose>

precision.
cast this double (4.5) to an int, I know that I am going to <loose>

precision

Please, everyone, look at this:

lose: (looz), to be unsuccessful in retaining possession of, mislay

loose: (loos), not fastened, detached, etc.

As in: Don't lose your virginity to a loose woman.

That really drives me crazy above all other grammatical errors!


Nov 15 '05 #5
Definitely one of my pet peeves too, and also an indication of option
explicit and option strict never having been enforced by one's
grammatical upbringing! <grin/> Bottom line is, if you are a
professional software developer and possess an above - room -
temperature IQ, there's no excuse for not learning the syntax of your
own native language, English. . .

Same with "Like" and "as"....

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 15 '05 #6
Peter... I have mixed feelings about the grammar police. An occassional
correction is OK, but this is a C# newsgroup, not an English newsgroup.

Regards,
Jeff
Definitely one of my pet peeves too, and also an indication of option

explicit and option strict never having been enforced by one's
grammatical upbringing! <grin/><

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 15 '05 #7
"Joe Mayo" <jm***@nospamAtCSharpDashStation.com> wrote in message news:<#V**************@tk2msftngp13.phx.gbl>...

<helpful explanation>

Many thanks for your explanation, Joe - it helps a lot. I must admit,
though, that I am slightly surprised by this behaviour. I know that I
am explicitly asking for a conversion, but the conversion that I'm
explicitly asking for is from double to Test. What I actually get are
two conversions that I didn't ask for at all - one from double to int,
and then another from int to Test. What puzzles me is how the
potentially dangerous conversion from double to int gets silently
slipped into the equation.

If you folks will indulge my ignorance for a little longer, here's a
further example that muddies the waters for me. What follows is
another version of the original example, but this time using
user-defined types (MyInt, MyDouble) in place of built-in types. As
per the built-in types I've created an implicit conversion from MyInt
to MyDouble and an explicit conversion from MyDouble to MyInt. Based
on the earlier example and on Joe's explanation I had expected to see
a silent conversion from MyDouble to MyInt, and then from MyInt to
Test. What I actually get is the error that I originally expected to
get in the first example; namely, the explicit conversion from
MyDouble to Test is not possible.
class Test
{
public static implicit operator Test(MyInt i)
{
return new Test();
}
}

struct MyInt
{
public static implicit operator MyDouble(MyInt i)
{
return new MyDouble();
}
}

struct MyDouble
{
public static explicit operator MyInt(MyDouble d)
{
return new MyInt();
}
}

class Driver
{
public static void Main()
{
MyDouble d = new MyDouble();
//Test t = d; // error, as expected.
//Test t = (Test)d; // error for MyDouble/MyInt; why not for
double/int?
}
}

Thanks again

Steve Gough
Nov 15 '05 #8
Steve,

First of all, please don't correct my grammer, since English is not my
native language... sorry.

I understand your requierment regarding the compiler error. I have puzzled
myself with your problem again and again but found no possible reason for
this problem.
On the other hand, and even though I am aware that cast operators should
generaly speaking never throw exceptions, if you do provide an
implicit/explicit casting from double and in it throw an exception, you are
still guarentied that the cast will never happen (at run-time :(...):

class Class1

{

[STAThread]

static void Main(string[] args)

{

//Test y = 4.5; // error

Test Y = 5;

Test x = 4.5; // this throws an exception

}

}

class Test

{

public static implicit operator Test(int x)

{

return new Test();

}

public static implicit operator Test(double x)

{

throw new InvalidCastException("Cannot cast from double to Test");

}

}
Nov 15 '05 #9
The reason the explicit conversion succeeded in the original case was
because there was a standard conversion from double to int. There are two
categories of conversions, standard and user-defined. Standard conversions
are defined by C# and user-defined conversions are the conversion operators
that you add to your types. In my explanation, I introduce the notion of a
'single conversion operation', for which there is not an official
definition. However, I use the term for the purpose of explanation because
I feel it is central to identifying the problem and the work around. Here's
a short overview of how the conversion process works (a single conversion
operation):

1. Perform a standard conversion, if necessary, to the parameter type of an
available user-defined conversion.
2. Perform the user-defined conversion that matches a type after a standard
conversion occurs or with whatever type matched without a standard
conversion.
3. Perform a standard conversion from the results of the user-defined
conversion to the target type of the conversion.

Notice #2 where there is exactly one "user-defined" conversion. The
original case succeeded because there was 1) a standard explicit conversion
from double to int, 2) a user-defined conversion from int to Test, and 3) a
standard conversion was not required because the conversion operator used
already returned the target type specified.

Now, notice how the case with your user-defined types and user-defined
conversions is structured. Here you are trying to perform 1) a user-defined
conversion from MyDouble to MyInt, 2) a user-defined conversion from MyInt
to Test, and <kaboom> you won't get to 3 because C# will detect that what
you are doing is illegal and generate a compiler error. You are not allowed
to perform two or more user-defined conversions in a single conversion
operation. In other words, you can only have one user-defined conversion in
any single conversion operation.

Here's how to fix it:

Test t = (Test)(MyInt)d;

This performs a single user-defined conversion from MyDouble to MyInt, which
is a single conversion operation. Then it performs a user-defined
conversion from MyInt to Test, which is another single conversion operation.

On another note, for those of you who are enjoying my grammar mistakes in
this thread, please forgive any further transgressions. In particular, I
have been unable to identify the correct spelling of <kaboom>. <grin>

Joe
--
http://www.csharp-station.com

"Steve Gough" <st*************@hotmail.com> wrote in message
news:4a**************************@posting.google.c om...
"Joe Mayo" <jm***@nospamAtCSharpDashStation.com> wrote in message news:<#V**************@tk2msftngp13.phx.gbl>...
per the built-in types I've created an implicit conversion from MyInt
to MyDouble and an explicit conversion from MyDouble to MyInt. Based
on the earlier example and on Joe's explanation I had expected to see
a silent conversion from MyDouble to MyInt, and then from MyInt to
Test. What I actually get is the error that I originally expected to
get in the first example; namely, the explicit conversion from
MyDouble to Test is not possible.
class Test
{
public static implicit operator Test(MyInt i)
{
return new Test();
}
}

struct MyInt
{
public static implicit operator MyDouble(MyInt i)
{
return new MyDouble();
}
}

struct MyDouble
{
public static explicit operator MyInt(MyDouble d)
{
return new MyInt();
}
}

class Driver
{
public static void Main()
{
MyDouble d = new MyDouble();
//Test t = d; // error, as expected.
//Test t = (Test)d; // error for MyDouble/MyInt; why not for
double/int?
}
}

Nov 15 '05 #10
Hi Picho,

I think you have it the other way around. Implicit conversions, which don't
require a cast, should never throw an exception and should never lose
information. On the other hand, the purpose of explict conversions is to
force the developer to make a concious decision when casting one type to
another when the results may result in data loss. Explicit conversions can
throw exceptions.

Also, please see my response to Steve for an explanation of why he is seeing
the behavior that appears in his sample code.

As far as grammar goes, I've been around the world and butchered many
languages in my path. I've always appreciated the grace and patience that
people in other countries extend to me when communicating. For me, there is
no excuse for making mistakes in my native language. (<joking>For the
grammar police: Go ahead and frame that and put it on the wall if it makes
you happy. </joking>) However, these groups bring the whole world together
in a community of people interested and passionate about their profession.
I would only hope that others practice tolerance and continue to embrace and
welcome everyone regardless of where in this small world they come from
and/or how well they communicate. :)

Joe
--
http://www.csharp-station.com

"Picho" <pi***@telhai.ac.il> wrote in message
news:OP**************@TK2MSFTNGP09.phx.gbl...
Steve,

First of all, please don't correct my grammer, since English is not my
native language... sorry.

I understand your requierment regarding the compiler error. I have puzzled
myself with your problem again and again but found no possible reason for
this problem.
On the other hand, and even though I am aware that cast operators should
generaly speaking never throw exceptions, if you do provide an
implicit/explicit casting from double and in it throw an exception, you are still guarentied that the cast will never happen (at run-time :(...):

class Class1

{

[STAThread]

static void Main(string[] args)

{

//Test y = 4.5; // error

Test Y = 5;

Test x = 4.5; // this throws an exception

}

}

class Test

{

public static implicit operator Test(int x)

{

return new Test();

}

public static implicit operator Test(double x)

{

throw new InvalidCastException("Cannot cast from double to Test");

}

}

Nov 15 '05 #11
"Joe Mayo" <jm***@nospamAtCSharpDashStation.com> wrote in message news:<Oq**************@TK2MSFTNGP10.phx.gbl>...
The reason the explicit conversion succeeded in the original case was
because there was a standard conversion from double to int.


Ahhh - I think I finally understand what is happening. Many thanks,
Joe, for your very clear explanations. I was missing the role that
these standard coversions play. Thanks too to Picho for your
suggestion - the addition of an explicit conversion from double which
throws an exception does indeed trap the unwanted conversion, albeit
at runtime rather than compile time.
Thanks all,
Steve
Nov 15 '05 #12

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,...
1
by: Christophe Poucet | last post by:
Hellom I have an issue with implicit conversions. Apparently when one calls an operator on a class Y which has a conversion operator to class X which has the operator . Sadly it will not do...
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...
11
by: Aaron Queenan | last post by:
Given the classes: class Class { public static implicit operator int(Class c) { return 0; } } class Holder
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...
10
by: Pieter Breed | last post by:
Hi All, Please excuse me, but the bulk of my post will be a code post. It describes some weirdness with regards to the implicit casting operator. The crux of the problem is this: I want to...
3
by: utab | last post by:
Dear all, I was trying to write a more complex program, and while searching for sth in my reference C++ primer, by Lippman. I had a question in the mind, see the code below #include <string>...
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...
8
by: jonpb | last post by:
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...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

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.