Is casting the same thing as converting?

前端 未结 11 905
失恋的感觉
失恋的感觉 2020-11-27 17:01

In Jesse Liberty\'s Learning C# book, he says \"Objects of one type can be converted into objects of another type. This is called casting.\"

If you investigate the I

相关标签:
11条回答
  • 2020-11-27 17:21

    According to Table 1-7 titled "Methods for Explicit Conversion" on page 55 in Chapter 1, Lesson 4 of MCTS Self-Paced Training Kit (Exam 70-536): Microsoft® .NET Framework 2.0—Application Development Foundation, there is certainly a difference between them.

    System.Convert is language-independent and converts "Between types that implement the System.IConvertible interface."

    (type) cast operator is a C#-specific language feature that converts "Between types that define conversion operators."

    Furthermore, when implementing custom conversions, advice differs between them.

    Per the section titled How to Implement Conversion in Custom Types on pp. 56-57 in the lesson cited above, conversion operators (casting) are meant for simplifying conversions between numeric types, whereas Convert() enables culture-specific conversions.

    Which technique you choose depends on the type of conversion you want to perform:

    • Define conversion operators to simplify narrowing and widening conversions between numeric types.

    • Implement System.IConvertible to enable conversion through System.Convert. Use this technique to enable culture-specific conversions.

    • ...

    It should be clearer now that since the cast conversion operator is implemented separately from the IConvertible interface, that Convert() is not necessarily merely another name for casting. (But I can envision where one implementation may refer to the other to ensure consistency).

    0 讨论(0)
  • 2020-11-27 17:27

    The simple answer is: it depends.

    For value types, casting will involve genuinely converting it to a different type. For instance:

    float f = 1.5f;
    int i = (int) f; // Conversion
    

    When the casting expression unboxes, the result (assuming it works) is usually just a copy of what was in the box, with the same type. There are exceptions, however - you can unbox from a boxed int to an enum (with an underlying type of int) and vice versa; likewise you can unbox from a boxed int to a Nullable<int>.

    When the casting expression is from one reference type to another and no user-defined conversion is involved, there's no conversion as far as the object itself is concerned - only the type of the reference "changes" - and that's really only the way that the value is regarded, rather than the reference itself (which will be the same bits as before). For example:

    object o = "hello";
    string x = (string) o; // No data is "converted"; x and o refer to the same object
    

    When user-defined conversions get involved, this usually entails returning a different object/value. For example, you could define a conversion to string for your own type - and this would certainly not be the same data as your own object. (It might be an existing string referred to from your object already, of course.) In my experience user-defined conversions usually exist between value types rather than reference types, so this is rarely an issue.

    All of these count as conversions in terms of the specification - but they don't all count as converting an object into an object of a different type. I suspect this is a case of Jesse Liberty being loose with terminology - I've noticed that in Programming C# 3.0, which I've just been reading.

    Does that cover everything?

    0 讨论(0)
  • 2020-11-27 17:28

    Casting always means changing the data type of an object. This can be done for instance by converting a float value into an integer value, or by reinterpreting the bits. It is usally a language-supported (read: compiler-supported) operation.

    The term "converting" is sometimes used for casting, but it is usually done by some library or your own code and does not necessarily result in the same as casting. For example, if you have an imperial weight value and convert it to metric weight, it may stay the same data type (say, float), but become a different number. Another typical example is converting from degrees to radian.

    0 讨论(0)
  • 2020-11-27 17:38

    The difference there is whether the conversion is implicit or explicit. The first one up there is a cast, the second one is a more explicit call to a function that converts. They probably go about doing the same thing in different ways.

    0 讨论(0)
  • 2020-11-27 17:41

    Casting involves References

    List<int> myList = new List<int>();
    //up-cast
    IEnumerable<int> myEnumerable = (IEnumerable<int>) myList;
    //down-cast
    List<int> myOtherList = (List<int>) myEnumerable;
    

    Notice that operations against myList, such as adding an element, are reflected in myEnumerable and myOtherList. This is because they are all references (of varying types) to the same instance.

    Up-casting is safe. Down-casting can generate run-time errors if the programmer has made a mistake in the type. Safe down-casting is beyond the scope of this answer.

    Converting involves Instances

    List<int> myList = new List<int>();
    int[] myArray = myList.ToArray();
    

    myList is used to produce myArray. This is a non-destructive conversion (myList works perfectly fine after this operation). Also notice that operations against myList, such as adding an element, are not reflected in myArray. This is because they are completely seperate instances.

    decimal w = 1.1m;
    int x = (int)w;
    

    There are operations using the cast syntax in C# that are actually conversions.

    0 讨论(0)
  • 2020-11-27 17:42

    The best explanation that I've seen can be seen below, followed by a link to the source:

    "... The truth is a bit more complex than that. .NET provides three methods of getting from point A to point B, as it were.

    First, there is the implicit cast. This is the cast that doesn't require you to do anything more than an assignment:

    int i = 5;
    double d = i;
    

    These are also called "widening conversions" and .NET allows you to perform them without any cast operator because you could never lose any information doing it: the possible range of valid values of a double encompasses the range of valid values for an int and then some, so you're never going to do this assignment and then discover to your horror that the runtime dropped a few digits off your int value. For reference types, the rule behind an implicit cast is that the cast could never throw an InvalidCastException: it is clear to the compiler that the cast is always valid.

    You can make new implicit cast operators for your own types (which means that you can make implicit casts that break all of the rules, if you're stupid about it). The basic rule of thumb is that an implicit cast can never include the possibility of losing information in the transition.

    Note that the underlying representation did change in this conversion: a double is represented completely differently from an int.

    The second kind of conversion is an explicit cast. An explicit cast is required wherever there is the possibility of losing information, or there is a possibility that the cast might not be valid and thus throw an InvalidCastException:

    double d = 1.5;
    int i = (int)d;
    

    Here you are obviously going to lose information: i will be 1 after the cast, so the 0.5 gets lost. This is also known as a "narrowing" conversion, and the compiler requires that you include an explicit cast (int) to indicate that yes, you know that information may be lost, but you don't care.

    Similarly, with reference types the compiler requires explicit casts in situations in which the cast may not be valid at run time, as a signal that yes, you know there's a risk, but you know what you're doing.

    The third kind of conversion is one that involves such a radical change in representation that the designers didn't provide even an explicit cast: they make you call a method in order to do the conversion:

    string s = "15";
    int i = Convert.ToInt32(s);
    

    Note that there is nothing that absolutely requires a method call here. Implicit and explicit casts are method calls too (that's how you make your own). The designers could quite easily have created an explicit cast operator that converted a string to an int. The requirement that you call a method is a stylistic choice rather than a fundamental requirement of the language.

    The stylistic reasoning goes something like this: String-to-int is a complicated conversion with lots of opportunity for things going horribly wrong:

    string s = "The quick brown fox";
    int i = Convert.ToInt32(s);
    

    As such, the method call gives you documentation to read, and a broad hint that this is something more than just a quick cast.

    When designing your own types (particularly your own value types), you may decide to create cast operators and conversion functions. The lines dividing "implicit cast", "explicit cast", and "conversion function" territory are a bit blurry, so different people may make different decisions as to what should be what. Just try to keep in mind information loss, and potential for exceptions and invalid data, and that should help you decide."

    • Bruce Wood, November 16th 2005

    http://bytes.com/forum/post1068532-4.html

    0 讨论(0)
提交回复
热议问题