@@ -136,3 +136,284 @@ class TypeName
136136
137137$object.MemberMethod2 ()
138138# @@@@@@@@@@@@@ reference
139+
140+
141+ # PowerShell documentation examples
142+ # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes
143+
144+ # Example 1 - Minimal definition
145+ class Device {
146+ # @@@@@@ definition
147+ [string ]$Brand
148+ }
149+
150+ $dev = [Device ]::new()
151+ # @@@ reference
152+ $dev.Brand = " Fabrikam, Inc."
153+ $dev
154+
155+
156+ # Example 2 - Class with instance members
157+ class Book {
158+ # @@@@ definition
159+ # Class properties
160+ [string ] $Title
161+ [string ] $Author
162+ [string ] $Synopsis
163+ [string ] $Publisher
164+ [datetime ] $PublishDate
165+ [int ] $PageCount
166+ [string []] $Tags
167+ # Default constructor
168+ Book() { $this.Init (@ {}) }
169+ # @@@@ reference
170+ # Convenience constructor from hashtable
171+ Book([hashtable ]$Properties ) { $this.Init ($Properties ) }
172+ # @@@@ reference
173+ # Common constructor for title and author
174+ Book([string ]$Title , [string ]$Author ) {
175+ $this.Init (@ {Title = $Title ; Author = $Author })
176+ # @@@@ reference
177+ }
178+ # Shared initializer method
179+ [void ] Init([hashtable ]$Properties ) {
180+ # @@@@ definition
181+ foreach ($Property in $Properties.Keys ) {
182+ $this .$Property = $Properties .$Property
183+ }
184+ }
185+ # Method to calculate reading time as 2 minutes per page
186+ [timespan ] GetReadingTime() {
187+ # @@@@@@@@@@@@@@ definition
188+ if ($this.PageCount -le 0 ) {
189+ throw ' Unable to determine reading time from page count.'
190+ }
191+ $Minutes = $this.PageCount * 2
192+ return [timespan ]::new(0 , $Minutes , 0 )
193+ # @@@ reference
194+ }
195+ # Method to calculate how long ago a book was published
196+ [timespan ] GetPublishedAge() {
197+ # @@@@@@@@@@@@@@@ definition
198+ if (
199+ $null -eq $this.PublishDate -or
200+ $this.PublishDate -eq [datetime ]::MinValue
201+ ) { throw ' PublishDate not defined' }
202+
203+ return (Get-Date ) - $this.PublishDate
204+ # @@@@@@@@ reference
205+ }
206+ # Method to return a string representation of the book
207+ [string ] ToString() {
208+ # @@@@@@@@ definition
209+ return " $ ( $this.Title ) by $ ( $this.Author ) ($ ( $this.PublishDate.Year ) )"
210+ }
211+ }
212+
213+ [BookList ]::Add([Book ]::new(@ {
214+ # @@@ reference
215+ # @@@ reference
216+ Title = ' The Fellowship of the Ring'
217+ Author = ' J.R.R. Tolkien'
218+ Publisher = ' George Allen & Unwin'
219+ PublishDate = ' 1954-07-29'
220+ PageCount = 423
221+ Tags = @ (' Fantasy' , ' Adventure' )
222+ }))
223+
224+ [BookList ]::Find({
225+ # @@@@ reference
226+ param ($b )
227+
228+ $b.PublishDate -gt ' 1950-01-01'
229+ }).Title
230+
231+ [BookList ]::FindAll({
232+ # @@@@@@@ reference
233+ param ($b )
234+
235+ $b.Author -match ' Tolkien'
236+ }).Title
237+
238+ [BookList ]::Remove($Book )
239+ # @@@@@@ reference
240+ [BookList ]::Books.Title
241+
242+ [BookList ]::RemoveBy(' Author' , ' J.R.R. Tolkien' )
243+ # @@@@@@@@ reference
244+ " Titles: $ ( [BookList ]::Books.Title) "
245+
246+ [BookList ]::Add($Book )
247+ # @@@ reference
248+ [BookList ]::Add($Book )
249+ # @@@ reference
250+
251+
252+ # Example 3 - Class with static members
253+ class BookList {
254+ # @@@@@@@@ definition
255+ # Static property to hold the list of books
256+ static [System.Collections.Generic.List [Book ]] $Books
257+ # Static method to initialize the list of books. Called in the other
258+ # static methods to avoid needing to explicit initialize the value.
259+ static [void ] Initialize() { [BookList ]::Initialize($false ) }
260+ # @@@@@@@@@@ definition
261+ # @@@@@@@@@@ reference
262+ static [bool ] Initialize([bool ]$Force ) {
263+ # @@@@@@@@@@ definition
264+ if ([BookList ]::Books.Count -gt 0 -and -not $Force ) {
265+ return $false
266+ }
267+
268+ [BookList ]::Books = [System.Collections.Generic.List [Book ]]::new()
269+ # @@@ reference
270+
271+ return $true
272+ }
273+ # Ensure a book is valid for the list.
274+ static [void ] Validate([book ]$Book ) {
275+ # @@@@@@@@ definition
276+ $Prefix = @ (
277+ ' Book validation failed: Book must be defined with the Title,'
278+ ' Author, and PublishDate properties, but'
279+ ) -join ' '
280+ if ($null -eq $Book ) { throw " $Prefix was null" }
281+ if ([string ]::IsNullOrEmpty($Book.Title )) {
282+ # @@@@@@@@@@@@@ reference
283+ throw " $Prefix Title wasn't defined"
284+ }
285+ if ([string ]::IsNullOrEmpty($Book.Author )) {
286+ # @@@@@@@@@@@@@ reference
287+ throw " $Prefix Author wasn't defined"
288+ }
289+ if ([datetime ]::MinValue -eq $Book.PublishDate ) {
290+ throw " $Prefix PublishDate wasn't defined"
291+ }
292+ }
293+ # Static methods to manage the list of books.
294+ # Add a book if it's not already in the list.
295+ static [void ] Add([Book ]$Book ) {
296+ # @@@ definition
297+ [BookList ]::Initialize()
298+ # @@@@@@@@@@ reference
299+ [BookList ]::Validate($Book )
300+ # @@@@@@@@ reference
301+ if ([BookList ]::Books.Contains($Book )) {
302+ # @@@@@@@@ reference
303+ throw " Book '$Book ' already in list"
304+ }
305+
306+ $FindPredicate = {
307+ param ([Book ]$b )
308+
309+ $b.Title -eq $Book.Title -and
310+ $b.Author -eq $Book.Author -and
311+ $b.PublishDate -eq $Book.PublishDate
312+ }.GetNewClosure()
313+ if ([BookList ]::Books.Find($FindPredicate )) {
314+ # @@@@ reference
315+ throw " Book '$Book ' already in list"
316+ }
317+
318+ [BookList ]::Books.Add($Book )
319+ # @@@ reference
320+ }
321+ # Clear the list of books.
322+ static [void ] Clear() {
323+ # @@@@@ definition
324+ [BookList ]::Initialize()
325+ # @@@@@@@@@@ reference
326+ [BookList ]::Books.Clear()
327+ # @@@@@ reference
328+ }
329+ # Find a specific book using a filtering scriptblock.
330+ static [Book ] Find([scriptblock ]$Predicate ) {
331+ # @@@@ definition
332+ [BookList ]::Initialize()
333+ # @@@@@@@@@@ reference
334+ return [BookList ]::Books.Find($Predicate )
335+ # @@@@ reference
336+ }
337+ # Find every book matching the filtering scriptblock.
338+ static [Book []] FindAll([scriptblock ]$Predicate ) {
339+ [BookList ]::Initialize()
340+ # @@@@@@@@@@ reference
341+ return [BookList ]::Books.FindAll($Predicate )
342+ # @@@@@@@ reference
343+ }
344+ # Remove a specific book.
345+ static [void ] Remove([Book ]$Book ) {
346+ # @@@@@@ definition
347+ [BookList ]::Initialize()
348+ # @@@@@@@@@@ reference
349+ [BookList ]::Books.Remove($Book )
350+ # @@@@@@ reference
351+ }
352+ # Remove a book by property value.
353+ static [void ] RemoveBy([string ]$Property , [string ]$Value ) {
354+ # @@@@@@@@ definition
355+ [BookList ]::Initialize()
356+ # @@@@@@@@@@ reference
357+ $Index = [BookList ]::Books.FindIndex({
358+ # @@@@@@@@@ reference
359+ param ($b )
360+ $b .$Property -eq $Value
361+ }.GetNewClosure())
362+ if ($Index -ge 0 ) {
363+ [BookList ]::Books.RemoveAt($Index )
364+ # @@@@@@@@ reference
365+ }
366+ }
367+ }
368+
369+
370+ # Example 4 - Class definition with and without Runspace affinity
371+
372+ # Class definition with Runspace affinity (default behavior)
373+ class UnsafeClass {
374+ # @@@@@@@@@@@ definition
375+ static [Object ] ShowRunspaceId($Val ) {
376+ # @@@@@@@@@@@@@@ definition
377+ return [pscustomobject ]@ {
378+ ThreadId = [Threading.Thread ]::CurrentThread.ManagedThreadId
379+ RunspaceId = [runspace ]::DefaultRunspace.Id
380+ }
381+ }
382+ }
383+
384+ $unsafe = [UnsafeClass ]::new()
385+ # @@@ reference
386+
387+ while ($true ) {
388+ 1 .. 10 | ForEach-Object - Parallel {
389+ # @@@@@@@@@@@@@@ reference
390+ Start-Sleep - ms 100
391+ # @@@@@@@@@@@ reference
392+ ($Using :unsafe )::ShowRunspaceId($_ )
393+ }
394+ }
395+
396+ # Class definition with NoRunspaceAffinity attribute
397+ [NoRunspaceAffinity ()]
398+ class SafeClass {
399+ # @@@@@@@@@ definition
400+ static [Object ] ShowRunspaceId($Val ) {
401+ # @@@@@@@@@@@@@@ definition
402+ return [pscustomobject ]@ {
403+ ThreadId = [Threading.Thread ]::CurrentThread.ManagedThreadId
404+ RunspaceId = [runspace ]::DefaultRunspace.Id
405+ }
406+ }
407+ }
408+
409+ $safe = [SafeClass ]::new()
410+ # @@@ reference
411+
412+ while ($true ) {
413+ 1 .. 10 | ForEach-Object - Parallel {
414+ # @@@@@@@@@@@@@@ reference
415+ Start-Sleep - ms 100
416+ # @@@@@@@@@@@ reference
417+ ($Using :safe )::ShowRunspaceId($_ )
418+ }
419+ }
0 commit comments