'New' cannot be used on a type parameter that does not have a 'New' constraint

  • Thread starter Thread starter Siegfried Heintze
  • Start date Start date
S

Siegfried Heintze

On line 5 of the program below I get the error message in the subject line.
(1) How may I correct it?
(2) How may I enhance my Arr class to work with a foreach statement?
(3) In C++ I can pass integer constants (like 1990) as template (generic)
parameters. Can I do that in VB.NET or must I use the constructor for that?

Thanks,
Siegfried





Module Module1
Class Arr(Of T)
Private data() As T
Public Sub New(ByVal n As Integer)
data = New T(n)
End Sub
Default Public Property Item(ByVal index As Integer) As T
Get
Return data(index - 1990)
End Get
Set(ByVal Value As T)
data(index - 1990) = Value
End Set
End Property
End Class
Declare Function _getch Lib "msvcrt.dll" () As Integer
Sub Main(ByVal args() As String)
Dim out As System.IO.TextWriter = System.Console.Out
Dim arr1 As Arr(Of Double) = New Arr(Of Double)(3)
Dim arr2 As Arr(Of String) = New Arr(Of String)(3)
arr1(1990) = 1.3
arr1(1991) = 4.5
arr1(1992) = 3
arr2(1990) = "A"
arr2(1991) = "B"
arr2(1992) = "C"
Dim ii As Integer
For ii = 1990 To 1992
out.WriteLine(arr1(ii) + ":" + arr2(ii))
Next
out.Write("hit return to continue: ")
_getch()
End Sub
End Module
 
It looks like you are using generics inappropriately here. From what I can
tell, you are using generics to build arrays of sizes that will be known
later. Because the Doubld type does not have a constructor, yet you are
trying to make a new instance of a Double array (T(n)), you get the error.

Try this:

Private data As T()
Private arraySize As Integer

Public Sub New(ByVal n As Integer)
ReDim data(n)
End Sub


To be able to use For Each, the class must implement the IEnumerable
interface.

I can't help you with your C++ question.
 
Thanks! That works! Can you explain the logic of using redim instead of new?
It seems new should work.
Siegfried
 
All types in .NET are either Reference types or Value types. Reference
types are loaded into the managed "heap" of memory and need to be
instantiated, while Value types are loaded into the "stack" of memroy and do
not get instantiated in order to use them.

For example, if we need an Integer variable, we don't write:

Dim x As New Integer

Because Integer is a value type, we just decleare x is of the type Integer.

On the other hand, if we need a new StreamReader (which is a class and
therefore a Reference type), we need to make an instance of it on the heap
as in:

Dim sr As New System.IO.StreamReader()

An array of type Double is a value type and so you don't instantiate it
using the "New" keyword, you just declare it and populate it.

Since you know you are going to want an array of type T, you declare it as
follows:

Dim myArray As T()

The parenthesis indicate that it's not just a T you want to declare, but an
array of T. But, at the time you declare T(), you don't know the size of
the array you'll need. Visual Basic allows you to re-define the array size
after it's already been declared using the ReDim keyword. So, since you
find out how big the array needs to be in your New method (constructor),
that's the place to ReDim the array with the correct size as in:

ReDim myArray(n)

-Scott
 
Since you know you are going to want an array of type T, you declare it as
follows:

Dim myArray As T()

The parenthesis indicate that it's not just a T you want to declare, but
an array of T. But, at the time you declare T(), you don't know the size
of the array you'll need.

So what you are saying is that when I declare an array I also allocate one
(whether I wanted to allocate one or not -- unlike C#)?

Thanks,
Siegfried
 
You allocate the memory address for one, but without specifying an array
size, you need to re-size the memory later when the correct size is known.
 
Back
Top