Condividi tramite


Confronto di proprietà ed elementi

Le proprietà e gli elementi MSBuild sono entrambi utilizzati per passare informazioni alle attività, valutare condizioni e archiviare valori a cui è possibile fare riferimento nel file di progetto.

  • Le proprietà sono coppie nome/valore. Per ulteriori informazioni, vedere Proprietà di MSBuild.

  • Gli elementi sono oggetti che in genere rappresentano file. Agli oggetti elemento è possibile associare raccolte di metadati. I metadati sono coppie nome/valore. Per ulteriori informazioni, vedere Elementi MSBuild.

Scalari e vettori

Poiché le proprietà MSBuild sono coppie nome/valore che presentano un unico valore stringa, spesso vengono descritte come scalari. Poiché i tipi di elemento MSBuild sono elenchi di elementi, spesso vengono descritti come vettori. Tuttavia, in pratica, le proprietà possono rappresentare più valori e i tipi di elemento possono presentare un solo o nessun elemento.

Inserimento di dipendenze di destinazione

Per comprendere come le proprietà possono rappresentare più valori, si consideri un modello di utilizzo comune per aggiungere una destinazione a un elenco di destinazioni da compilare. In genere questo elenco viene rappresentato da un valore di proprietà, con i nomi di destinazione separati da punto e virgola.

<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

Di solito la proprietà BuildDependsOn viene utilizzata come argomento di un attributo DependsOnTargets relativo a più destinazioni. Ciò di fatto comporta la conversione di tale proprietà in un elenco di elementi. È possibile eseguire l'override di questa proprietà per aggiungere una destinazione o modificare l'ordine di esecuzione delle destinazioni. Di seguito è riportato un esempio:

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        CustomBuild;
    </BuildDependsOn>
</PropertyGroup>

aggiunge la destinazione CustomBuild all'elenco di destinazione, assegnando a BuildDependsOn il valore BeforeBuild;CoreBuild;AfterBuild;CustomBuild.

A partire da MSBuild 4.0, l'inserimento di dipendenze di destinazione risulta deprecato. Utilizzare invece gli attributi AfterTargets e BeforeTargets. Per ulteriori informazioni, vedere Ordine di compilazione delle destinazioni.

Conversioni fra stringhe ed elenchi di elementi

MSBuild esegue conversioni fra tipi di elemento e valori stringa in base alle esigenze. Per comprendere come un elenco di elementi può diventare un valore stringa, si consideri ciò che si verifica quando un tipo di elemento viene utilizzato come valore di una proprietà MSBuild:

<ItemGroup>
    <OutputDir Include="KeyFiles\;Certificates\" />
  </ItemGroup>
<PropertyGroup>
    <OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>

Il tipo di elemento OutputDir presenta un attributo Include con il valore "KeyFiles\;Certificates\". MSBuild analizza questa stringa ricavandone due elementi: KeyFiles\ e Certificates\. Quando il tipo di elemento OutputDir viene utilizzato come valore della proprietà OutputDirList, MSBuild converte o "appiattisce" il tipo di elemento nella stringa separata da punto e virgola "KeyFiles\;Certificates\".

Proprietà ed elementi nelle attività

Le proprietà e gli elementi vengono utilizzati come input e output delle attività MSBuild. Per ulteriori informazioni, vedere Attività di MSBuild.

Le proprietà vengono passate alle attività come attributi. All'interno dell'attività, una proprietà MSBuild viene rappresentata da un tipo di proprietà il cui valore può essere convertito da e in una stringa. I tipi di proprietà supportati includono bool, char, DateTime, Decimal, Double, int, string e qualsiasi tipo che ChangeType può gestire.

Gli elementi vengono passati alle attività come oggetti ITaskItem. All'interno dell'attività, ItemSpec rappresenta il valore dell'elemento e GetMetadata ne recupera i metadati.

L'elenco di elementi di un tipo di elemento può essere passato come una matrice di oggetti ITaskItem. A partire da .NET Framework 3.5, gli elementi possono essere rimossi da un elenco di elementi in una destinazione tramite l'attributo Remove. Poiché gli elementi possono essere rimossi da un elenco di elementi, è possibile che un tipo di elemento presenti zero elementi. Se si passa un elenco di elementi a un'attività, il codice di quest'ultima deve tener conto di questa possibilità.

Ordine di valutazione di proprietà ed elementi

Durante la fase di valutazione di una compilazione, i file importati vengono incorporati nella build nell'ordine in cui si trovano. Le proprietà e gli elementi vengono definiti in tre passaggi nell'ordine seguente:

  • Le proprietà vengono definite e modificate nell'ordine in cui si trovano.

  • Le definizioni degli elementi vengono create e modificate nell'ordine in cui si trovano.

  • Gli elementi vengono definiti e modificati nell'ordine in cui si trovano.

Durante la fase di esecuzione di una compilazione, le proprietà e gli elementi definiti all'interno delle destinazioni vengono valutati insieme in un'unica fase nell'ordine in cui si trovano.

Tuttavia, ci sono altri punti da tener presente. Quando si definisce una proprietà, una definizione di elemento o un elemento, ne viene valutato il valore. L'analizzatore di espressioni espande la stringa che specifica il valore. L'espansione della stringa dipende dalla fase di compilazione. Ecco un ordine di valutazione di proprietà ed elementi più dettagliato:

  • Durante la fase di valutazione di una compilazione:

    • Le proprietà vengono definite e modificate nell'ordine in cui si trovano. Le funzioni di proprietà vengono eseguite. I valori delle proprietà nella forma $(NomeProprietà) vengono espansi all'interno di espressioni. Il valore delle proprietà viene impostato sull'espressione espansa.

    • Le definizioni degli elementi vengono create e modificate nell'ordine in cui si trovano. Le funzioni di proprietà sono già state espanse all'interno di espressioni. I valori dei metadati vengono impostati sulle espressioni espanse.

    • I tipi di elemento vengono definiti e modificati nell'ordine in cui si trovano. I valori degli elementi nella forma @(TipoElemento) vengono espansi. Anche le trasformazioni degli elementi vengono espanse. Le funzioni e i valori delle proprietà sono già stati espansi all'interno di espressioni. I valori dell'elenco di elementi e dei metadati vengono impostati sulle espressioni espanse.

  • Durante la fase di esecuzione di una compilazione:

    • Le proprietà e gli elementi definiti all'interno di destinazioni vengono valutati insieme nell'ordine in cui si trovano. Le funzioni di proprietà vengono eseguite e i valori delle proprietà vengono espansi all'interno di espressioni. Anche i valori e le trasformazioni degli elementi vengono espansi. I valori delle proprietà, dei tipi di elemento e dei metadati vengono impostati sulle espressioni espanse.

Effetti non evidenti dell'ordine di valutazione

Nella fase di valutazione di una compilazione, le proprietà vengono valutate prima degli elementi. Ciononostante, le proprietà possono presentare valori che sembrano dipendere dai valori degli elementi. Si consideri lo script seguente.

<ItemGroup>
    <KeyFile Include="KeyFile.cs">
        <Version>1.0.0.3</Version>
    </KeyFile>
</ItemGroup>
<PropertyGroup>
    <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<Target Name="AfterBuild">
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

L'esecuzione dell'attività Message comporta la visualizzazione di questo messaggio:

KeyFileVersion: 1.0.0.3

Questa situazione si verifica poiché di fatto il valore di KeyFileVersion è la stringa "@(KeyFile->'%(Version)')". Quando la proprietà è stata definita, gli elementi e le relative trasformazioni non sono stati espansi. Pertanto, alla proprietà KeyFileVersion è stato assegnato il valore della stringa non espansa.

Durante la fase di esecuzione della compilazione, quando l'attività Message viene elaborata, MSBuild espande la stringa "@(KeyFile->'%(Version)')" in "1.0.0.3".

Si noti che lo stesso messaggio sarebbe stato visualizzato anche se l'ordine dei gruppi delle proprietà e degli elementi fosse stato invertito.

Come secondo esempio, si consideri ciò che può succedere quando i gruppi delle proprietà e degli elementi si trovano all'interno di destinazioni:

<Target Name="AfterBuild">
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

L'attività Message visualizza questo messaggio:

KeyFileVersion: 

Questa situazione si verifica perché durante la fase di esecuzione della compilazione, i gruppi delle proprietà e degli elementi definiti all'interno di destinazioni vengono valutati contemporaneamente e dall'alto verso il basso. Quando la proprietà KeyFileVersion viene definita, KeyFile è sconosciuto. Pertanto, la trasformazione dell'elemento genera una stringa vuota.

In questo caso, invertendo l'ordine dei gruppi delle proprietà e degli elementi è possibile ripristinare il messaggio originale:

<Target Name="AfterBuild">
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

Il valore di KeyFileVersion viene impostato su "1.0.0.3" e non su "@(KeyFile->'%(Version)')". L'attività Message visualizza questo messaggio:

KeyFileVersion: 1.0.0.3

Vedere anche

Altre risorse

Concetti avanzati relativi a MSBuild