Narrowing Array Conversion with Option Strict On

  • Thread starter Thread starter Codemonkey
  • Start date Start date
C

Codemonkey

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.
 
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.
 
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.
 
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).ToString)
'With option strict off you do not
'have to use the directcast but and than it is
'MessageBox.Show(a(2)(2).ToString) 'but I would not do that
'I show this to make it more classic looking for you.
End Sub
End Module
///
 
Sorry for a stupid question, but is it possible to do a narrowing conversion
with an object array with Option Strict On in VB?

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).CallDerivedMethod() ' oops....



Mattias
 
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.
 
Cheers,

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

Thanks for the help,

Trev.
 
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.
 
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.
 
Back
Top