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 11 7620
"Steve Gough" <st************ *@hotmail.com> wrote in message
news:4a******** *************** ***@posting.goo gle.com... 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
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!
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*******@hotp op.com> wrote in message
news:OA******** ******@TK2MSFTN GP10.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!
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***@nospamAt CSharpDashStati on.com> wrote in message
news:#E******** ******@TK2MSFTN GP10.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*******@hotp op.com> wrote in message news:OA******** ******@TK2MSFTN GP10.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!
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!
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!
"Joe Mayo" <jm***@nospamAt CSharpDashStati on.com> wrote in message news:<#V******* *******@tk2msft ngp13.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
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 InvalidCastExce ption("Cannot cast from double to Test");
}
}
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.goo gle.com... "Joe Mayo" <jm***@nospamAt CSharpDashStati on.com> wrote in message
news:<#V******* *******@tk2msft ngp13.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? } } This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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):
|
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 implicit conversion
for this case, however if instead of class X we just use a pointer
then the implicit conversion will work.
Anyone have any ideas why it will not do implicit conversion?
|
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
|
by: Aaron Queenan |
last post by:
Given the classes:
class Class
{
public static implicit operator int(Class c)
{
return 0;
}
}
class Holder
|
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"
| |
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 set a property on a class that takes an interface instance.
I have a class that can cast implicit to a class that impliments said
interface,
but the compiler moans and says it cannot cast implicitly like that.
|
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>
#include <iostream>
#include <cstring>
int main(){
|
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.
|
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 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...
|
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,...
|
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...
| |
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...
|
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...
|
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...
|
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...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |