none
Différence entre static readonly et const RRS feed

  • Question

  • Bonjour ,

    Je pense que cette question est plutot pour Alex Petrescu puisqu'elle est en rapport avec ses C# FAQ

    J'ai créé une classe qui ne comporte de champs,propriétés et méthodes statiques ( sans constructeur statique ), est-ce que les 2 déclarations suivantes sont identiques ?

    private const Assembly _appass = Assembly.GetEntryAssembly();
    public const Assembly AppAss
    {
       get
       {
         return _appass;
       }
    }
    

    et

    private static readonly Assembly _appass = Assembly.GetEntryAssembly();
    public static readonly Assembly AppAss
    {
       get
       {
          return _appass;
       } 
    }
    

    Je vois un avantage ( dans ce cas très précis ) à utiliser const ( c'est plus court à taper ) que static readonly. Il y a un autre avantage ( moins évident ) , j'utilise assez souvent CODEDOM pour générer automatiquement des classes et dans ce cas , MemberAttributes.Const est plus naturel à utiliser puisqu'il n'y a pas d'équivalent pour static readonly .

    Ma question peut paraître stupide  mais je préfère demander confirmation avant de commencer un programme utilisant CODEDOM pour créer une base SQL Server image d'une base "mère".

    Bonne journée 


    Mark Post as helpful if it provides any help.Otherwise,leave it as it is.
    mardi 7 décembre 2010 22:53

Réponses

Toutes les réponses

  • Bonjour,

    Le code suivant ne compile pas :

    private const Assembly _appass = Assembly.GetEntryAssembly();
    public const Assembly AppAss
    {
     get
     {
      return _appass;
     }
    }
    
    

    const s'utilise uniquement avec les types primitifs et la classe string.
    const agit au niveau de la compilation comme un #define de C, en effet le compilateur va remplacer dans l'IL directement toutes les constantes par des valeurs.

    readonly permet uniquement de s'assurer qu'un champ ne sera pas modifié après instanciation de la classe (statique ou non).

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    mardi 7 décembre 2010 23:01
    Modérateur
  • Bonjour,

    La différence est que static readonly se définit au runtime au contraire de const qui se définit à la compilation.

    Un membre static readonly pourra donc être assigné une seule fois par la classe qui le définit.

    Par contre attention un objet marqué comme static readonly ne pourra être assigné qu'une seule fois à l'exécution mais ses propriétés resteront modifiables!


    Christophe Argento
    Architecte .Net/Consultant chez Ineat Conseil
    Blog: http://christopheargento.com
    mercredi 8 décembre 2010 09:38
  • Bonjour,

    Juste pour préciser que l'initialisation du membre static readonly peut donc être effectué

    - soit à l'initialisation du champ

    - soit dans un constructeur statique

    public class Test
    {
     private static readonly int JeSuisStaticReadOnly = 0;
    
     static Test(){
      JeSuisStaticReadOnly = 1;
     }
    }
    
    

     

    mercredi 8 décembre 2010 17:18
    Modérateur
  • Bonjour Gilles ( et les autres ),

    Merci pour vôtre réponse et je reconnais que j'ai fait une erreur dans l'exemple de code que j'ai donné.

    Je cherche à créer avec CodeDom un code comme

       /// <summary>
       /// Private field for AppAss
       /// </summary>
       private static readonly Assembly _appass = Assembly.GetEntryAssembly();
       /// <summary>
       /// Assembly of the currently executing application
       /// </summary>
       public static Assembly AppAss
       {
        get
        {
         return _appass;
        }
       }
    
    

     

    Or, il n'est pas possible de créer ce code avec System.CodeDom, il n'y a aucun moyen "rapide et simple" pour créer ce code ( MemberAttributes.Const ne peut être utilisé ). Je vais essayer d'utiliser un CodeSnippet pour générer ce code car j'ai besoin d'une méthode Set qui soit private .Si cela ne marche pas , j'utiliserai la méthode "classique" de la méthode Get construite à partir d'un CodeSnippet pour obtenir un code du style

    public static Assembly AppAss
    {
      get
      {
       return Assembly.GetEntryAssembly();
      }
    }
    

    à moins que quelqu'un me dise que c'est une hérésie ( je suis loin d'être un expert en VC# ) ou m'indique une façon plus élégante de générer ce code sans CodeSnippet ou mieux encore une meilleure présentation du code.Par contre, je risque d'avoir des problèmes pour la génération du code correspondant à :

       /// <summary>
       /// Private field for AppProcess
       /// </summary>
       private static readonly Process _appprocess = Process.GetCurrentProcess();
       /// <summary>
       /// Process associated with the current execution of the application
       /// </summary>
       public static Process AppProcess
       {
        get
        {
         return _appprocess;
        }
       }
    
       /// <summary>
       /// Private field for AppProcessId
       /// </summary>
       private static readonly Int32 _appprocessid = _appprocess.Id;
       /// <summary>
       /// Unique identifier of the AppProcess process
       /// </summary>
       public static Int32 AppProcessId
       {
        get
        {
         return _appprocessid;
        }
       }
    
       /// <summary>
       /// Private field for AppProcessName
       /// </summary>
       private static readonly String _appprocessname = _appprocess.ProcessName;
       /// <summary>
       /// Name of the AppProcess process
       /// </summary>
       public static String AppProcessName
       {
        get
        {
         return _appprocessname;
        }
       }
    
       /// <summary>
       /// Private field for AppProcessStartTime
       /// </summary>
       private static readonly DateTime _appprocessstarttime = _appprocess.StartTime;
       /// <summary>
       /// Start date/time of the AppProcess process
       /// </summary>
       public static DateTime AppProcessStartTime
       {
        get
        {
         return _appprocessstarttime;
        }
       }
    
    

    Pour ce dernier extrait de code, je pars de _appprocess pour "construire les autres champs et propriétés et il est possible que cela soit une erreur ( mais au fait , est-ce que DateTime est un type de données comme System.String ou System.Int32 ou du style Assembly , c'est-à-dire une vraie classe ? ). Pour _appprocess, je sais que j'aurai les mêmes problèmes (  car Process ) que pour _appass ( Assembly )

    En tout cas, merci à tous pour vos réponses qui m'ont permis d'éliminer certaines incompréhensions sur les variables static readonly  ou const en VC#.

    Je vous tiendrez au courant de mes résultats si vous êtes intéressés et si vous êtes d'accord.

    Bonne journée et merci encore

    PS: Est-ce quelqu'un pourrait me dire si mes problèmes de génération de code avec CodeDom devraient être postés dans ce forum ou Développement .Net (général) ? ( je suis moins à l'aise avec VB qu'avec VC# ). Celà m'éviterait d'obliger un modérateur à déplacer ma discussion


    Mark Post as helpful if it provides any help.Otherwise,leave it as it is.
    • Modifié Papy Normand jeudi 9 décembre 2010 20:47 Rajout de les autres dans le bonjour
    jeudi 9 décembre 2010 20:46
  • Bonjour,

    1/PS: Est-ce quelqu'un pourrait me dire si mes problèmes de génération de code avec CodeDom devraient être postés dans ce forum ou Développement .Net (général) ? ( je suis moins à l'aise avec VB qu'avec VC# ). Celà m'éviterait d'obliger un modérateur à déplacer ma discussion.
    Votre question se trouve dans le bon forum...

    2/Avant de continuer avec CodeDOM avez vous essayé les templates T4, c'est beaucoup plus facile et lisible pour générer du code. (Par contre un template vise uniquement un langage).

    3/Les champs readonly ne sont pas supporté par CodeDOM : http://blogs.msdn.com/b/bclteam/archive/2005/03/16/396915.aspx

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    • Marqué comme réponse Papy Normand jeudi 9 décembre 2010 23:08
    jeudi 9 décembre 2010 21:22
    Modérateur
  • Bonjour Gilles ( et les autres ),

    1/ Merci, je saurai où poster

    2/ Pourriez-vous fournir quelques liens sur les templates T4 ( j'ai déjà vu ce terme mais j'ignore où et quand )

    3/ je sais qu'il est impossible de générer simplement les champs readonly.C'est pour cela que j'ai voulu passer par une définition "const".Or il est impossible d'initialiser un const de type Assembly.D'où la solution du CodeSnippet qui permet de générer un "bout de code" comme return Assembly.GetEntryAssembly() dans un Get.Mais ce que vous me dites est une confirmation de cette impossibilité

    Bonne journée ( non bonne nuit )


    Mark Post as helpful if it provides any help.Otherwise,leave it as it is.
    jeudi 9 décembre 2010 23:07
  • Vous trouverez pas mal d'informations sur la génération de code avec T4 à partir de cette page:

    http://msdn.microsoft.com/en-us/library/bb126445.aspx
    Christophe Argento
    Architecte .Net/Consultant chez Ineat Conseil
    Blog: http://christopheargento.com
    • Marqué comme réponse Papy Normand vendredi 10 décembre 2010 08:30
    vendredi 10 décembre 2010 01:24
  • Bonjour Christophe,

    Merci pour le lien. Je commence à étudier les liens connexes. A priori, un sujet très,très interessant, dommage qu'l reste un peu confidentiel ( comme SMO, mon préféré )

    Bonne journée


    Mark Post as helpful if it provides any help.Otherwise,leave it as it is.
    vendredi 10 décembre 2010 08:30