Collection initializers for read-only collection properties in VB.NET?
I'm trying to support Basic.NET on my framework so I'm trying to convert C# 4 code to Basic.NET 10. Microsoft is committed to "co-evolve" these two but I'm having a problem with collection initialization...
I found that I can initialize a collection much like in C#:
Dim list = New List(Of Int32) From {1, 2, 3, 4, 5, 6, 7, 8, 9}
Great! But this doesn't work when initializing a read-only collection property. For example, if I have this class:
Public Class Class1
Private ReadOnly list = New List(Of Int32)
Public Read开发者_Python百科Only Property ListProp() As List(Of Int32)
Get
Return list
End Get
End Property
End Class
I'm not able to initialize it this way:
Dim class1 = New Class1 With {.ListProp = New List(Of Int32) From {1, 2, 3, 4, 5, 6, 7, 8, 9}}
Or this way:
Dim class1 = New Class1 With {.ListProp = {1, 2, 3, 4, 5, 6, 7, 8, 9}}
I get a "Property 'ListProp' is 'ReadOnly'." message which is correct but, it says here that collection initializer are supported in Basic.NET, where the Add method is automatically called. Am I missing something or isn't this supported for properties? C# 4 supports this...
Thanks in advance, aalmada
EDIT:
Here is the equivalent compilable C# code for reference:
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class Class1
{
private readonly List<Int32> list = new List<Int32>();
public List<Int32> ListProp
{
get
{
return this.list;
}
}
}
class Program
{
static void Main(string[] args)
{
// a collection initialization
var list = new List<Int32> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// a read-only collection property initialization
var class1 = new Class1
{
ListProp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
};
}
}
}
You're trying to set the ListProp
property to a new List(Of Int32)
instance.
Since it's ReadOnly
, you can't do that.
You are trying to assign to ListProp
property new object. You can modify readonly fields only in the class constructor.
From other side, you have an ability to modify readonly list's elements everywhere.
EDIT: According to Meta-Knight's comment, this doesn't compile. However, I'll leave it in place for educational purposes. It would surprise me if this really weren't supported, but I can't work out the VB syntax without spending more time messing around on it.
Well, I would try the equivalent to the C# code, i.e.
' No idea whether this would work or not, but worth a try
Dim class1 = New Class1 With {.ListProp = From {1, 2, 3, 4, 5, 6, 7, 8, 9}}
Now the lack of New List(Of Int32)
- just as in C# you would write:
var class1 = new Class1 { ListProp = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };
Trying to include the new List<int>
in the C# code would fail in the same way, so try removing it from the VB version...
The problem here is that the collection property is marked ReadOnly
, not with the initializer. At no point can a read-only property appear on the left side of the assignment operator.
As a workaround, you could pass the collection in as an argument to the constructor, and expose it as a ReadOnlyCollection<T>
(System.Collections.ObjectModel.ReadOnlyCollection<T>
).
Unless the class takes in a constructor argument and assigns it to the private list
variable, you cannot initialize the readonly
property directly.
Can you keep it more simple? like this?
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim list = New List(Of Int32) From {1, 2, 3, 4, 5, 6, 7, 8, 9}
Dim class1x = New Class1(New List(Of Int32) From {1, 2, 3, 4, 5, 6, 7, 8, 9})
Dim class1y = New Class1(list)
Dim list2 = New List(Of Int32)
list2 = class1x.ListProp
list2 = class1y.ListProp
End Sub
End Class
Public Class Class1
Sub New(l As List(Of Int32))
list = l
End Sub
Private ReadOnly list = New List(Of Int32)
Public ReadOnly Property ListProp() As List(Of Int32)
Get
Return list
End Get
End Property
End Class
精彩评论