Dan Field ha un powershell script che accetta una classe di output xsd.exe e trasforma i suoi array in elenchi generici. Questo ha funzionato bene per me con una classe semplice, ma non so quanto bene scala. Ho incollato la sceneggiatura qui sotto. Chiama da un prompt dei comandi come questo
"$(TargetFrameworkSDKToolsDirectory)xsd.exe" /c "$(ProjectDir)ImportedPartCanonical.xsd" "$(ProjectDir)ProjectCanonical.xsd" /n:Tallan.BT.PipelineComponents
powershell.exe -ExecutionPolicy Unrestricted -file "$(solutiondir)\PowerShellScripts\PostProcessXsdExe.ps1" ProjectCanonical.cs "$(SolutionDir)Tallan.BT.PipelineComponents\SerializedClasses\ProjectCanonical.cs"
Vedere il link per la spiegazione completa.
# Author: Dan Field ([email protected])
# posted on blog.tallan.com/2016/03/10/xsd-exe-arrays-and-specified
# Purpose: fix the 'specified' attribute and convert arrays to list from XSD.exe generated classes
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,Position=1)]
[string]$inputFile,
[Parameter(Mandatory=$true,Position=2)]
[string]$outputFile,
[switch]$DeleteInputFile
)
# much faster than using Get-Content and/or Out-File/Set-Content
$writer = [System.IO.StreamWriter] $outputFile
$reader = [System.IO.StreamReader] $inputFile
# used to track Specified properties
$setterDict = @{}
while (($line = $reader.ReadLine()) -ne $null)
{
$thisStart = $line.IndexOf("this.") # will be used for
$brackets = $line.IndexOf("[]") # indicates an array that will be converted to a Generic List
# assume that any private field that contains "Specified" needs to be grabbed
if (($line.IndexOf("private") -gt -1) -and ($line.IndexOf("Specified") -gt -1))
{
# get the field name
$varName = $line.Split("{' ',';'}", [System.StringSplitOptions]::RemoveEmptyEntries)[-1]
# use field name as a key, minus the ending "Specified" portion, e.g. fieldNameSpecified -> fieldName
# the value in the dictionary will be added to setters on the main property, e.g. "this.fieldNameSpecified = true;"
$setterDict.Add($varName.Substring(0, $varName.IndexOf("Specified")), "this." + $varName + " = true;")
# output the line as is
$writer.WriteLine($line)
}
# find property setters that aren't for the *Specified properties
elseif (($thisStart -gt -1) -and ($line.IndexOf(" = value") -gt -1) -and ($line.IndexOf("Specified") -lt 0))
{
# get the field name
$thisStart += 5
$varName = $line.Substring($thisStart, $line.IndexOf(' ', $thisStart) - $thisStart)
# see if there's a "Specified" property for this one
if ($setterDict.ContainsKey($varName) -eq $true)
{
# set the Specified property whenever this property is set
$writer.WriteLine((' ' * ($thisStart - 5)) + $setterDict[$varName])
}
# output the line itself
$writer.WriteLine($line)
}
elseif ($brackets -gt 0) # change to List<T>
{
$lineParts = $line.Split(' ')
foreach ($linePart in $lineParts)
{
if ($linePart.Contains("[]") -eq $true)
{
$writer.Write("System.Collections.Generic.List<" + $linePart.Replace("[]", "> "))
}
else
{
$writer.Write($linePart + " ")
}
}
$writer.WriteLine();
}
else # just output the original line
{
$writer.WriteLine($line)
}
}
if ($DeleteInputFile -eq $true)
{
Remove-Item $inputFile
}
# Make sure the file gets fully written and clean up handles
$writer.Flush();
$writer.Dispose();
$reader.Dispose();
fonte
2017-09-03 16:39:07
Sei semplice sostituire la linea che contiene una matrice [] con una lista? Oppure vengono modificate anche altre righe del codice? –
Gero
Solo le linee in cui sono coinvolti gli array fissi. Lo strumento sta analizzando il C# -source e trasferendolo in un AST (Abstract Syntax Tree) con l'aiuto di NRefactory. Quindi i cambiamenti sono applicati in modo robusto. L'idea era di toccare il meno possibile dell'originale. – EvilBad
sì, carica l'ultima versione. – Gero