visual studio run para method how extension ejecutar create configurar como code c# .net visual-studio msbuild extension-methods

run - visual studio code execute c#



Detectar la versiĆ³n del marco de destino en tiempo de compilaciĆ³n (6)

La pregunta SO vinculada con ''crear N configuraciones diferentes'' es ciertamente una opción, pero cuando tuve una necesidad de esto, simplemente agregué elementos condicionales DefinineConstants, así que en mi Debug | x86 (por ejemplo) después de DefineConstants para DEBUG; TRACE, Agregué estos 2, comprobando el valor en TFV que se estableció en el primer PropertyGroup del archivo csproj.

<DefineConstants Condition=" ''$(TargetFrameworkVersion)'' == ''v4.0'' ">RUNNING_ON_4</DefineConstants> <DefineConstants Condition=" ''$(TargetFrameworkVersion)'' != ''v4.0'' ">NOT_RUNNING_ON_4</DefineConstants>

No necesitas ambas cosas, obviamente, pero está ahí para dar ejemplos de comportamientos eq y ne - #else y #elif también funcionan bien :)

class Program { static void Main(string[] args) { #if RUNNING_ON_4 Console.WriteLine("RUNNING_ON_4 was set"); #endif #if NOT_RUNNING_ON_4 Console.WriteLine("NOT_RUNNING_ON_4 was set"); #endif } }

Podría cambiar entre la orientación 3.5 y 4.0 y haría lo correcto.

Tengo un código que hace uso de los Métodos de extensión, pero compila bajo .NET 2.0 usando el compilador en VS2008. Para facilitar esto, tuve que declarar ExtensionAttribute:

/// <summary> /// ExtensionAttribute is required to define extension methods under .NET 2.0 /// </summary> public sealed class ExtensionAttribute : Attribute { }

Sin embargo, ahora me gustaría que la biblioteca en la que está contenida esa clase también sea compilable bajo .NET 3.0, 3.5 y 4.0, sin la advertencia ''ExtensionAttribute se define en varios lugares''.

¿Hay alguna directiva de tiempo de compilación que pueda usar para incluir solo ExtensionAttribute cuando la versión de framework que se está orientando es .NET 2?


Los grupos de propiedades solo sobrescriben, por lo que esto anularía la configuración de DEBUG , TRACE u otros. - Ver la evaluación de propiedad de MSBuild

Además, si la propiedad DefineConstants se establece desde la línea de comandos, cualquier cosa que se haga dentro del archivo del proyecto es irrelevante ya que esa configuración se convierte en global de solo lectura. Esto significa que sus cambios a ese valor fallan silenciosamente.

Ejemplo de mantenimiento de constantes definidas existentes:

<CustomConstants Condition=" ''$(TargetFrameworkVersion)'' == ''v2.0'' ">V2</CustomConstants> <CustomConstants Condition=" ''$(TargetFrameworkVersion)'' == ''v4.0'' ">V4</CustomConstants> <DefineConstants Condition=" ''$(DefineConstants)'' != '''' And ''$(CustomConstants)'' != '''' ">$(DefineConstants);</DefineConstants> <DefineConstants>$(DefineConstants)$(CustomConstants)</DefineConstants>

Esta sección DEBE venir después de cualquier otra constante definida, ya que es poco probable que se configuren de manera aditiva

Solo definí esos 2 porque eso es principalmente lo que me interesa de mi proyecto, mmm.

Ver también: Propiedades comunes del proyecto MsBuild



Me gustaría contribuir con una respuesta actualizada que resuelva algunos problemas.

Si configura DefineConstants en lugar de CustomConstants terminará, en la línea de comandos Debug de Conditional Compilation, después de algún cambio de versión de framework, con constantes condicionales duplicadas (es decir: NETFX_451; NETFX_45; NETFX_40; NETFX_35; NETFX_30; NETFX_20; NETFX_35; NETFX_30 ; NETFX_20;). Este es el VersionSpecificSymbols.Common.prop que resuelve cualquier problema.

<!-- ********************************************************************* Defines the Compile time symbols Microsoft forgot Modelled from https://msdn.microsoft.com/en-us/library/ms171464.aspx ********************************************************************* Author: Lorenzo Ruggeri ([email protected]) --> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Choose> <When Condition=" $(TargetFrameworkVersion) == ''v2.0'' "> <PropertyGroup> <CustomConstants >$(CustomConstants);NETFX_20</CustomConstants> </PropertyGroup> </When> <When Condition=" $(TargetFrameworkVersion) == ''v3.0'' "> <PropertyGroup> <CustomConstants >$(CustomConstants);NETFX_30</CustomConstants> <CustomConstants >$(CustomConstants);NETFX_20</CustomConstants> </PropertyGroup> </When> <When Condition=" $(TargetFrameworkVersion) == ''v3.5'' "> <PropertyGroup> <CustomConstants >$(CustomConstants);NETFX_35</CustomConstants> <CustomConstants >$(CustomConstants);NETFX_30</CustomConstants> <CustomConstants >$(CustomConstants);NETFX_20</CustomConstants> </PropertyGroup> </When> <Otherwise> <PropertyGroup> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.5.1'')))) &gt;= 0">$(CustomConstants);NETFX_451</CustomConstants> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.5'')))) &gt;= 0">$(CustomConstants);NETFX_45</CustomConstants> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.0'')))) &gt;= 0">$(CustomConstants);NETFX_40</CustomConstants> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''3.5'')))) &gt;= 0">$(CustomConstants);NETFX_35</CustomConstants> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''3.0'')))) &gt;= 0">$(CustomConstants);NETFX_30</CustomConstants> <CustomConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''2.0'')))) &gt;= 0">$(CustomConstants);NETFX_20</CustomConstants> </PropertyGroup> </Otherwise> </Choose> <PropertyGroup> <DefineConstants>$(DefineConstants);$(CustomConstants)</DefineConstants> </PropertyGroup> </Project>


Tengo algunas sugerencias para mejorar las respuestas dadas hasta ahora:

  1. Use Version.CompareTo (). Las pruebas de igualdad no funcionarán para versiones posteriores del framework, que aún no se han nombrado. P.ej

    <CustomConstants Condition=" ''$(TargetFrameworkVersion)'' == ''v4.0'' ">

    no coincidirá con v4.5 o v4.5.1, lo que normalmente desea.

  2. Use un archivo de importación para que estas propiedades adicionales solo tengan que definirse una vez. Recomiendo mantener el archivo de importación bajo control de fuente, para que los cambios se propaguen junto con los archivos del proyecto, sin esfuerzo adicional.

  3. Agregue el elemento de importación al final de su archivo de proyecto, para que sea independiente de cualquier grupo de propiedades específico de la configuración. Esto también tiene el beneficio de requerir una sola línea adicional en su archivo de proyecto.

Aquí está el archivo de importación (VersionSpecificSymbols.Common.prop)

<!-- ****************************************************************** Defines the Compile time symbols Microsoft forgot Modelled from https://msdn.microsoft.com/en-us/library/ms171464.aspx ********************************************************************* --> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <DefineConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.5.1'')))) &gt;= 0">$(DefineConstants);NETFX_451</DefineConstants> <DefineConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.5'')))) &gt;= 0">$(DefineConstants);NETFX_45</DefineConstants> <DefineConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''4.0'')))) &gt;= 0">$(DefineConstants);NETFX_40</DefineConstants> <DefineConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''3.5'')))) &gt;= 0">$(DefineConstants);NETFX_35</DefineConstants> <DefineConstants Condition="$([System.Version]::Parse(''$(TargetFrameworkVersion.Substring(1))'').CompareTo($([System.Version]::Parse(''3.0'')))) &gt;= 0">$(DefineConstants);NETFX_30</DefineConstants> </PropertyGroup> </Project>

Agregar elemento de importación al archivo de proyecto

Refiéralo desde su archivo .csproj agregando al final, antes de la etiqueta.

… <Import Project="VersionSpecificSymbols.Common.prop" /> </Project>

Tendrá que arreglar la ruta para que apunte a la carpeta común / compartida donde puso este archivo.

Para usar los símbolos de tiempo de compilación

namespace VersionSpecificCodeHowTo { using System; internal class Program { private static void Main(string[] args) { #if NETFX_451 Console.WriteLine("NET_451 was set"); #endif #if NETFX_45 Console.WriteLine("NET_45 was set"); #endif #if NETFX_40 Console.WriteLine("NET_40 was set"); #endif #if NETFX_35 Console.WriteLine("NETFX_35 was set"); #endif #if NETFX_30 Console.WriteLine("NETFX_30 was set"); #endif #if NETFX_20 Console.WriteLine("NETFX_20 was set"); #else The Version specific symbols were not set correctly! #endif #if DEBUG Console.WriteLine("DEBUG was set"); #endif #if MySymbol Console.WriteLine("MySymbol was set"); #endif Console.ReadKey(); } } }

Un ejemplo común de "vida real"

Implementando Join (string delimiter, IEnumerable strings) Antes de .NET 4.0

// string Join(this IEnumerable<string> strings, string delimiter) // was not introduced until 4.0. So provide our own. #if ! NETFX_40 && NETFX_35 public static string Join( string delimiter, IEnumerable<string> strings) { return string.Join(delimiter, strings.ToArray()); } #endif

Referencias

Funciones de propiedad

Evaluación de propiedad de MSBuild

¿Puedo hacer que una directiva de preprocesador dependa de la versión de .NET Framework?

Compilación condicional según la versión del marco en C #


Use la reflexión para determinar si la clase existe. Si lo hace, entonces cree y use dinámicamente , de lo contrario use la clase de solución .Net2 que se puede definir, pero que no se usa para todas las otras versiones .net.

Aquí está el código que utilicé para una AggregateException que es .Net 4 y superior solamente:

var aggregatException = Type.GetType("System.AggregateException"); if (aggregatException != null) // .Net 4 or greater { throw ((Exception)Activator.CreateInstance(aggregatException, ps.Streams.Error.Select(err => err.Exception))); } // Else all other non .Net 4 or less versions throw ps.Streams.Error.FirstOrDefault()?.Exception ?? new Exception("Powershell Exception Encountered."); // Sanity check operation, should not hit.