Narrowing Array Conversion with Option Strict On

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Codemonkey

    Narrowing Array Conversion with Option Strict On

    Hi,

    Sorry for a stupid question, but is it possible to do a narrowing conversion
    with an object array with Option Strict On in VB?

    E.g:

    ------------------

    Dim aBase as Base() = {New Derived(), New Derived(), New Derived()}
    Dim aDerived as Derived()

    ' Compiler error with Option Strict On, Run Time "Invalid Cast" exception
    with Strict OFF
    aDerived = aBase


    ' Compiles with Strict On, still gets Run Time "Invalid Cast" exception
    aDerived = ctype(aBase, Derived())

    ------------------

    I would have thought that this is a valid assignment and a run time
    exception should only be raised if the objects held in aBase were not of
    type Derived. The sample in the help file seems to work fine for a narrowing
    conversion between an object array that contains strings and a string array,
    so why doesn't this work with inherited objects? Is it a case of my brain
    being fried on a Friday afternoon? ;)

    I can get around it by the Using Array.CopyTo method (which is probably the
    same thing that is done under the scenes), but would like a neater way of
    doing it.

    Thanks for your help.

    Trev.


  • Cor

    #2
    Re: Narrowing Array Conversion with Option Strict On

    Hi Codemonkey,

    Did you look what Ilist can do for you?

    Cor


    Comment

    • Codemonkey

      #3
      Re: Narrowing Array Conversion with Option Strict On

      > Did you look what Ilist can do for you?

      How do you mean? I know Arrays implement IList, but I don't see how I can
      use it to assign one array to another.


      Comment

      • Codemonkey

        #4
        Re: Narrowing Array Conversion with Option Strict On

        Extra Information regarding array conversion from the help files:

        --------------------
        You can convert an array type to a different array type provided the
        following conditions are met:

        a) The ranks of the two arrays must be the same; that is, they must have the
        same number of dimensions.
        However, the lengths of the respective dimensions do not need to be the
        same.


        b) The data types of the elements of both arrays must be reference types.
        You cannot convert an Integer array to a Long array, or even to an Object
        array, because at least one value type is involved.

        c) A conversion, either widening or narrowing, must be possible between the
        element types of the two arrays. An example that fails this requirement is
        an attempted conversion between a String array and an array of a class
        derived from System.Enum. These two types have nothing in common, and no
        conversion of any kind exists between them.

        -----------------------

        With my example in the first post:

        Requirement (a) is met because both arrays have a rank of 1.
        Requirement (b) is met because both types are of reference types
        Requirement (c) is met because the assignment is a narrowing conversion
        (Base to Derived is a narrowing conversion)


        Any thoughts?

        Trev.


        Comment

        • Cor

          #5
          Re: Narrowing Array Conversion with Option Strict On

          Hi Codemonkey,

          I once made this sample for someone and I thought it did look a little bit
          as your problem, but maybe I am wrong.

          Cor
          \\\
          Option Strict On
          Public Module Main
          ' Sample of an arraylist that itself contains 10 classic arrays.
          Public Sub Main()
          Dim a As New ArrayList
          Dim B() As Integer = {1, 2, 3, 4}
          For i As Integer = 0 To 9
          a.Add(B)
          Next
          MessageBox.Show (DirectCast(a(9 ), IList)(2).ToStr ing)
          'With option strict off you do not
          'have to use the directcast but and than it is
          'MessageBox.Sho w(a(2)(2).ToStr ing) 'but I would not do that
          'I show this to make it more classic looking for you.
          End Sub
          End Module
          ///

          [color=blue]
          > How do you mean? I know Arrays implement IList, but I don't see how I can
          > use it to assign one array to another.
          >
          >[/color]


          Comment

          • Mattias Sjögren

            #6
            Re: Narrowing Array Conversion with Option Strict On

            [color=blue]
            >Sorry for a stupid question, but is it possible to do a narrowing conversion
            >with an object array with Option Strict On in VB?[/color]

            Not the way you're doing it, no. However, if you change it to

            Dim aBase as Base() = New Derived() {New Derived(), New Derived(), New
            Derived()}

            it'll work. The actual array type must be Derived() (or something more
            derived), but your array reference can be Base().

            Imagine what would happen in the following situation if your code
            worked.

            Dim aBase as Base() = {New Derived(), New Derived(), New Derived()}
            ' pretend this works
            Dim aDerived as Derived() = ctype(aBase, Derived())
            ' this also affects aDerived since they refer to the same array
            aBase(0) = New Base()
            aDerived(0).Cal lDerivedMethod( ) ' oops....



            Mattias

            --
            Mattias Sjögren [MVP] mattias @ mvps.org
            http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
            Please reply only to the newsgroup.

            Comment

            • Codemonkey

              #7
              Re: Narrowing Array Conversion with Option Strict On

              Aha, I've found the problem - when creating the base array, you actually
              need to create a derived array like so:
              ---------------------------

              Dim aBase as Base() = New Derived() {New Derived(), New Derived(), New
              Derived()}
              Dim aDerived as Derived()

              aDerived = CType(aBase, Derived())

              ---------------------------

              I guess I misunderstood the way arrays are created and converted. Would I be
              right in saying that the Invalid Cast Exception is thrown because an array
              is essentially an object of a certain type and acts in a similar way to
              objects themselves (with the same inheritance rules)?

              In other words, would trying to do:
              -------------------
              Dim aBase as Base() = {New Derived(), New Derived(), New Derived()}
              Dim aDerived as Derived()

              aDerived = CType(aBase, Derived()) ' Won't work because aBase is Base, not
              Derived, even though it contains derived objects
              ---------------
              be similar to:
              ------------------

              Dim objBase as Base = New Base ' Note new Base, not new derived -
              Dim objDerived as Derived

              objDerived = ctype(objBase, Derived) ' won't work because objBase is Base,
              Not Derived - expected
              ------------------

              i.e. trying to assign a base instance to a derived variable instead of
              assigning a derived instance in a base variable to a derived variable?

              If so, I think the help requirements could be a bit clearer on this point.

              Also there should be no work on Fridays - a 4 day week is enough for my
              brain, thanks ;)

              Trev.


              Comment

              • Codemonkey

                #8
                Re: Narrowing Array Conversion with Option Strict On

                Cheers,

                Just figured this myself (in a roundabout kinda way). Makes sense now.

                Thanks for the help,

                Trev.

                "Mattias Sjögren" <mattias.dont.w ant.spam@mvps.o rg> wrote in message
                news:ezUqa3r1DH A.3116@TK2MSFTN GP11.phx.gbl...[color=blue]
                >[color=green]
                > >Sorry for a stupid question, but is it possible to do a narrowing[/color][/color]
                conversion[color=blue][color=green]
                > >with an object array with Option Strict On in VB?[/color]
                >
                > Not the way you're doing it, no. However, if you change it to
                >
                > Dim aBase as Base() = New Derived() {New Derived(), New Derived(), New
                > Derived()}
                >
                > it'll work. The actual array type must be Derived() (or something more
                > derived), but your array reference can be Base().
                >
                > Imagine what would happen in the following situation if your code
                > worked.
                >
                > Dim aBase as Base() = {New Derived(), New Derived(), New Derived()}
                > ' pretend this works
                > Dim aDerived as Derived() = ctype(aBase, Derived())
                > ' this also affects aDerived since they refer to the same array
                > aBase(0) = New Base()
                > aDerived(0).Cal lDerivedMethod( ) ' oops....
                >
                >
                >
                > Mattias
                >
                > --
                > Mattias Sjögren [MVP] mattias @ mvps.org
                > http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
                > Please reply only to the newsgroup.[/color]


                Comment

                • Codemonkey

                  #9
                  Re: Narrowing Array Conversion with Option Strict On

                  Cheers for the help, but it's not exactly what I meant.

                  After a bit of thought, I've sorted it out anyway (see other posts).

                  Trev.

                  "Cor" <non@non.com> wrote in message
                  news:OPiTOyr1DH A.4008@tk2msftn gp13.phx.gbl...[color=blue]
                  > Hi Codemonkey,
                  >
                  > I once made this sample for someone and I thought it did look a little bit
                  > as your problem, but maybe I am wrong.
                  >
                  > Cor
                  > \\\
                  > Option Strict On
                  > Public Module Main
                  > ' Sample of an arraylist that itself contains 10 classic arrays.
                  > Public Sub Main()
                  > Dim a As New ArrayList
                  > Dim B() As Integer = {1, 2, 3, 4}
                  > For i As Integer = 0 To 9
                  > a.Add(B)
                  > Next
                  > MessageBox.Show (DirectCast(a(9 ), IList)(2).ToStr ing)
                  > 'With option strict off you do not
                  > 'have to use the directcast but and than it is
                  > 'MessageBox.Sho w(a(2)(2).ToStr ing) 'but I would not do that
                  > 'I show this to make it more classic looking for you.
                  > End Sub
                  > End Module
                  > ///
                  >
                  >[color=green]
                  > > How do you mean? I know Arrays implement IList, but I don't see how I[/color][/color]
                  can[color=blue][color=green]
                  > > use it to assign one array to another.
                  > >
                  > >[/color]
                  >
                  >[/color]


                  Comment

                  • Peter Huang

                    #10
                    Re: Narrowing Array Conversion with Option Strict On

                    Hi,

                    I am glad the problem has been resolved.
                    If you have any concern on this issue, please post here.

                    Regards,
                    Peter Huang
                    Microsoft Online Partner Support
                    Get Secure! www.microsoft.com/security
                    This posting is provided "as is" with no warranties and confers no rights.

                    Comment

                    Working...