Conversion Operators


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-ansi-language: ES">One of my
many jobs here at MS is helping out with the .NET Framework Design Guidelines
Document.  Tonight I had to make a small tweak to a guideline I added last
week so I thought while I was in there I would post it here to see if folks had
comments.


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-ansi-language: ES"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-ansi-language: ES">—————————————————————————–


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-ansi-language: ES"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-ansi-language: ES">7.10
Conversion Operators
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> "urn:schemas-microsoft-com:office:office" />



  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do
    not
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">
    define cast operators in publicly exposed APIs. style="mso-spacerun: yes">  The exception to this rule is for
    creating “primitive” types such as Int32, Double, or DateTime. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do not
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">define
    casting operators outside of a types domain – for example Int32, Double, and
    Decimal are all numeric types – while DateTime is not. style="mso-spacerun: yes">  Therefore there should be no cast
    operator to go from a Double to a DateTime. style="mso-spacerun: yes">  A constructor is preferred in this
    case.  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do
    not
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold"> use
    cast operators in a surprising way. 
    That is only provide them where there is a strong expectation that they
    would be there and ideally some prior art that justifies
    them.

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do
    not
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold"> lose
    precision in implicit casts. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">For
    example, there should not be an implicit cast from style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Double style="mso-bidi-font-weight: bold"> to Int32 style="mso-bidi-font-weight: bold">, but there may be one from
    Int32 to Int64 style="mso-bidi-font-weight: bold">.

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold"> not
    throw exceptions from implicit casts because it is very difficult for the
    developer to understand what is happening. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">
    provide casts that operate on the whole object. The value that is cast
    represents the whole value being cast, not one sub part. For example, it is
    not appropriate for a Button to cast to a string by returning its
    caption. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do
    not
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">
    generate a semantically different value. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">For
    example, it is appropriate to convert a Time or TimeSpan into an Int. The Int
    still represents the time or duration. It does not make sense to convert a
    file name string such as, “c:\mybitmap.gif” into a Bitmap object. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

  • style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">Do
    style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: bold">cast
    values that are in the same domain. Do not cast values from different
    domains.  Casts operate within a
    particular domain of values. For example, numbers and strings are different
    domains. So it makes sense that an Int32 can cast to a Double. It does not
    make sense for an Int to cast to a String, because they are in different
    domains. style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">

 

Comments (3)

  1. Adam Hill says:

    Why the restriction in casting across domains?

    Is there some inherent speed/optimization/exception catching goodness with *not* casting.

    There is much casting wierdness in COMland (what domain is void ** in 🙂 ). Is this an attempt at a fresh start?

  2. Brad Abrams says:

    No, the "cross domain" thing is really about programming model. We don’t want users to try to cast things that are just different at a basic level. That is too "cute"…

  3. Duncan Smart says:

    "For example, it is appropriate to convert a Time or TimeSpan into an Int"
    what is a "Time"? Do you mean a DateTime?

Skip to main content