-
Oct 4th, 2024, 04:13 PM
#1
Thread Starter
Junior Member
Property setter not called when setting individual element of an array property.
Hi,
I'm using VisualStudio 2022 working in VB.Net targeting .NET framework 4.8.1
I have a class with a public property that is an array.
There is a private backing variable that is an array.
I want to fire an event when the property is changed.
When I pass a value to a single index of the array, the index is actually set without the setter ever being called.
My main issue is that the setter is not called so my data changed event does not fire.
But I am also curious how the private variable gets set without the setter being called.
If I build the array ahead of time and pass the whole array to the property at once the setter IS called.
So I have a workaround. But that's not really how I want to do it as the individual values may be set in different sections of code.
For instance, I may use a loop to initialize the data in the array but then later change single indices as conditions warrant.
Can someone explain why this happens and how to fix it?
Here is a simple console app that demonstrates the issue.
Code:
Module Module1
Sub Main()
Console.WriteLine($"Adding feet one at a time.{vbCrLf}")
Dim Monster1 As New Thing
For Index As Integer = 1 To 17
Monster1.Feet(Index) = New Foot(Index)
Next
Console.WriteLine($"Notice that the property setter was never called.{vbCrLf} But output below indicates the property was set.")
For I As Integer = 1 To 17
Console.WriteLine($"Foot Number {Monster1.Feet(I).FootNum} was created.")
Next
Console.WriteLine($"{vbCrLf}{vbCrLf}Adding feet all at once.")
Dim Monster2 As New Thing
Dim Feet(17) As Foot
For Index As Integer = 1 To 17
Feet(Index) = New Foot(Index)
Next
Monster2.Feet = Feet
Console.WriteLine($"Notice that the property setter was called.{vbCrLf}")
Console.Write("Press any key to continue...")
Console.ReadKey(True)
End Sub
Class Thing
Private _Feet(17) As Foot
Public Property Feet As Foot()
Get
Return _Feet
End Get
Set(value As Foot())
Console.WriteLine("Foot property setter is called.")
_Feet = value
OnFeetChanged()
End Set
End Property
Private Sub OnFeetChanged()
' Raise Event
End Sub
End Class
Class Foot
Private _FootNum As Integer
Public ReadOnly Property FootNum As Integer
Get
Return _FootNum
End Get
End Property
Public Sub New(FootNumber As Integer)
_FootNum = FootNumber
End Sub
End Class
End Module
And here is the console output:
Adding feet one at a time.
Notice that the property setter was never called.
But output below indicates the property was set.
Foot Number 1 was created.
Foot Number 2 was created.
Foot Number 3 was created.
Foot Number 4 was created.
Foot Number 5 was created.
Foot Number 6 was created.
Foot Number 7 was created.
Foot Number 8 was created.
Foot Number 9 was created.
Foot Number 10 was created.
Foot Number 11 was created.
Foot Number 12 was created.
Foot Number 13 was created.
Foot Number 14 was created.
Foot Number 15 was created.
Foot Number 16 was created.
Foot Number 17 was created.
Adding feet all at once.
Foot property setter is called.
Notice that the property setter was called.
-
Oct 4th, 2024, 05:12 PM
#2
Re: Property setter not called when setting individual element of an array property.
Property setters don’t work with collections, lists, or arrays. There’s no way to pass an index. You could probably work something out with an observable collection. I can’t explain at the moment, but this link might help…
https://www.codeproject.com/Articles...mply-Explained
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Oct 4th, 2024, 10:52 PM
#3
Re: Property setter not called when setting individual element of an array property.
Why would you expect a setter to be executed when you're not setting the property? If you have a property that is an array and you set an element in that array then you're not setting the property. You're getting the property and then setting an element on the array you get. This:
Code:
Feet(Index) = New Foot(Index)
never assigns anything to Feet, so of course the setter is not executed. That code is functionally equivalent to this:
Code:
Dim var = Feet 'Get the Feet property value.
var(Index) = New Foot(Index)
You execute the property getter to get the array object, then setting the element of that object has nothing at all to do with the property.
One option would be to not expose the array itself via the property but only store it internally and then use an indexed property:
Code:
Class Thing
Private _Feet(17) As Foot
Public Property Feet(index As Integer) As Foot
Get
Return _Feet(index)
End Get
Set(value As Foot)
Console.WriteLine("Foot property setter is called.")
_Feet(index) = value
OnFeetChanged()
End Set
End Property
Private Sub OnFeetChanged()
' Raise Event
End Sub
End Class
You then can't access the array itself via the property, so setting an element by index will invoke the property setter and the getter will only get one element at a time by index. If you wanted to be able to access the entire array, you could add a method that would return it or, probably better, a copy of it.
-
Oct 5th, 2024, 03:40 PM
#4
Re: Property setter not called when setting individual element of an array property.
Ok, I was wrong about the index, but property getters and setters aren’t ideal for arrays, as jmcilhinney has shown you.
Have a look at ReadOnly and WriteOnly Properties and OverLoading Properties. You could set the array elements in a WriteOnly Property, and retrieve the array from an Overloaded ReadOnly Property.
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Oct 6th, 2024, 06:52 AM
#5
Re: Property setter not called when setting individual element of an array property.
Here's what i meant...
Code:
Private _feet([ubound of array]) As Foot
Public Overloads WriteOnly Property Feet(ByVal index As Integer) As Foot
Set(ByVal value As Foot)
_feet(index) = value
End Set
End Property
Public Overloads ReadOnly Property Feet() As Foot()
Get
Return _feet
End Get
End Property
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|