Friday, November 23, 2007

Immutable data class generator: Skeleton implementation

I've made a little progress on my PowerShell DSL for data classes, and figured it's a good time to show it off.

Here's the input format at this point:

class MyClass {

field ([string]) S


(I'm using the ScriptBlock approach.) I generally like the syntax, except for the need to add parentheses around the type. The alternative is to use a fully-qualified string:

class MyClass {

field System.String S


I'm not sure which is better, but I'm going with the first one for now, because it allows a more specific type than string.

The basis of the implementation is to write methods named 'class' and 'field'. 'class' is simple; here's an excerpt of the important bits:

$class = New-Object System.CodeDom.CodeTypeDeclaration $name

$class.TypeAttributes = [System.Reflection.TypeAttributes]::NotPublic

$class.IsPartial = $true

$constructor = New-Object System.CodeDom.CodeConstructor

$class.Members.Add( $constructor ) Out-Null


The implementation of 'field' could go in several different ways. For now, I've written it to manipulate the class as appropriate, e.g.:

$field = New-Object System.CodeDom.CodeMemberField($type, $name)

$class.Members.Add( $field )

$ctorParameter = New-Object System.CodeDom.CodeParameterDeclarationExpression($type, $name)


$fieldReference = New-Object System.CodeDom.CodeFieldReferenceExpression(

(New-Object System.CodeDom.CodeThisReferenceExpression),



$ctorInitializer = New-Object System.CodeDom.CodeAssignStatement(


(New-Object System.CodeDom.CodeVariableReferenceExpression $name)


$constructor.Statements.Add( $ctorInitializer )

(I'd like to attach the full script, but I don't see a way to do that in blogspot). It generates this output:

internal partial class MyClass


public string S;

private MyClass(string S)


this.S = S;



EDIT: See PowerShell DSLs: Using hashtables and scriptblocks together for a different view of this code.

No comments:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.