Heritage : Empecher le partage d'une variable static

Résolu
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 - 12 déc. 2011 à 15:52
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 - 16 déc. 2011 à 09:39
Bonjour,

J'utilise une classe static pour effectuer des Logs dans toute mon application.
Je souhaite ajouter une classe dérivée pour faire un deuxième Log mais je souhaite empêcher que la variable static qui donne le chemin du fichier soit partagée entre la classe mère et la classe fille.

Est-ce que quelqu'un à une idée ?

Merci de votre aide.

Vincnet68.

10 réponses

cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
16 déc. 2011 à 09:09
Bonjour

ou quelque chose comme:

public class ClassLog
{
protected string _logFilePath = null;
public readonly static ClassLog Log = new ClassLog();
public static string LogFilePath { get { return Log._logFilePath; } set { Log._logFilePath = value; } }

public virtual void Add(string textToAdd)
{
if (LogFilePath == null)
throw new NullReferenceException("Le nom du fichier log n'a pas été initialisé");
//Ajoute au fichier
Console.WriteLine(string.Format("Ajoute [{0}] dans le fichier {1}", textToAdd, _logFilePath));
}
}
public class ClassLog2 : ClassLog
{

public readonly static new ClassLog2 Log = new ClassLog2();
public static new string LogFilePath { get { return Log._logFilePath; } set { Log._logFilePath = value; } }

public void Add(DateTime date, Exception ex)
{
if (LogFilePath == null)
{
ClassLog.Log.Add(" ClassLog2 : Le nom du fichier log n'a pas été initialisé");
//On le repasse à la classe mère...
ClassLog.Log.Add(string.Format("   ==> {0} {1}", date.ToString(), ex.Message));
return;
}

//Ajoute au fichier
Console.WriteLine(string.Format("Ajoute [{0} : {1}] dans le fichier {2}", date.ToString(), ex.Message, _logFilePath));
}
}


Utilisation:
static void Main(string[] args)
{
ClassLog.LogFilePath = "MonLog.log";
ClassLog2.LogFilePath = "MonLog2.log";

ClassLog.Log.Add("test pour ClassLog");
ClassLog2.Log.Add("test pour ClassLog 2");
ClassLog2.Log.Add(DateTime.Now, new InvalidProgramException("test pour ClassLog2"));

}

Bob.
C# is amazing, enjoy it!
3
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
16 déc. 2011 à 09:39
Voici la solution que j'ai trouvé
Classe de base :
  public sealed class Log
    {
        #region Déclarations et propriétés

        private string logFilePath;
        /// <summary>
        /// Path to save the file
        /// </summary>
        public string LogFilePath
        {
            get 
            { 
                return logFilePath; 
            }
            set
            {
                logFilePath = value;
            }
        }

        //Contructeur
        public Log()
        {

        }
      
        public void Add(object stringToAdd)
        {
            try
            {
                if (LogFilePath != "")
                {   //verify if the directory and file exist
                    FileInfo file = new FileInfo(LogFilePath);
                    if (!file.Directory.Exists) file.Directory.Create();

                    StreamWriter stream = null;

                    if (!file.Exists)
                        stream = file.CreateText();
                    else
                        stream = file.AppendText();
                    try
                    {
                        stream.Write(stringToAdd.ToString()); // empty line;
                    }
                    catch (Exception)
                    {
                    }
                    finally
                    {
                        try
                        {
                            stream.Close();
                        }
                        catch (Exception)
                        {
                        }
                        finally
                        {

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion //Fonctions Publiques


Classe qui ajoute les erreurs dans unfichier Log
 public class ExceptionLog
   {
       protected static Log log = new Log();

       public static string LogFilePath
       {
           get
           {
               return log.LogFilePath;
           }
           set
           {
               log.LogFilePath = value;
           }
       }
      
       public static void Add(Exception ex, bool exceptionAllreadyManaged = false)
       {
           StringBuilder exceptionString = new StringBuilder();
           exceptionString.AppendLine(); // empty line;
           try
           {
               exceptionString.AppendLine(System.Windows.Forms.Application.ProductName + " Version : " + System.Windows.Forms.Application.ProductVersion);
           }
           catch (Exception)
           {
               exceptionString.AppendLine("Exception by getting production name and version");
           }
           if (exceptionAllreadyManaged)
               exceptionString.Append("Erreur gérée (ajout pour suivi : ");
           else
               exceptionString.Append("Erreur non gérée : ");
           exceptionString.AppendLine("Exception : " + ex.ToString());
           exceptionString.AppendLine(DateTime.Now.ToString());
           exceptionString.AppendLine(Utils.StringFromException(ex));
           log.Add(exceptionString.ToString());

#if DEBUG
           if (!exceptionAllreadyManaged)
               Utils.ReportError(ex);
#endif
       }
   }


Classe pour autre Log
 class LogForData
    {
        protected static Log log = new Log();

        public static string LogFilePath
        {
            get
            {
                return log.LogFilePath;
            }
            set
            {
                log.LogFilePath = value;
            }
        }

        private static bool headerAdded = false;

        private static void addData(DateTime date, string data1)
        {
          
            StringBuilder strBuidler = new StringBuilder();
            strBuidler.Append(date.ToString("dd/MM/yy HH:mm:ss"));
            strBuidler.Append(";");
            strBuidler.Append(data1);
            strBuidler.AppendLine();
            log.Add(strBuidler.ToString());
        }

  public static void Add(DateTime date, string data1)
        {
              // Add Header
            if (!headerAdded)
            {
                log.Add("Date; Data1 \r\n");
                headerAdded = true;
            }
           addData( date,  data1);

        }


J'espère que cette solution pourra servir à d'autres.

Vincnet68
3
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
12 déc. 2011 à 16:18
Salut,

je t'avouerai ne pas bien comprendre ton problème.
Une classe statique ne peut être dérivée en C#.
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
12 déc. 2011 à 16:37
Salut,

La classe ne l'est pas mais les membres si (j'ai extrapolé dans mon explication désolé).

Je m'explique avec un exemple :
public Class Log1
{
    static string logFilePath = "";
    public static string LogFilePath
    {
        get { return Log.logFilePath; }
        set { Log.logFilePath = value; }
    }
    public static void Add(string textToAdd)
    {
        //ajout dans le fichier
    }
}
public Class Log2 : Log1
{
   
    public static void Add(DateTime date, Exception ex)
    {
        //ajout dans le fichier
    }
}


Mais je ne veux pas que Log1 et Log2 enregistre dans le même fichier et qu'ils restent tous les deux accessible depuis n'importe où dans mon appli avec Logx.Add() sans avoir besoin de les instancier.

J'espère que ma demande est plus claire, n'hésite pas si ce n'est pas le cas.

Merci

Vincnet68
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_jopop Messages postés 1540 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 1 août 2013 12
12 déc. 2011 à 18:54
Re,

oki doki pour la précision ;)

alors le principe serait de passer ta variable statique de la classe mère en "private" au lieu de "protected", et de la redéfinir dans la classe fille. Souci : toutes tes fonctions de la classe mère utilisant cette variable devront être recodées -> gain nul.

De manière général les statiques ne sont pas adaptées à l'héritage. Dans ton cas de figure on aurait pu penser à une interface ou une abstract, mais là aussi ça va coincer. Je pense que le plus propre pour toi serait de voir ta classe Log1 comme une pseudo-factory, associée à une enum répertoriant les différents type de log/manière de logger (avis perso).

désolé de pas pouvoir plus aider.
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
12 déc. 2011 à 19:11
Bonjour,

A la place d'une classe statique, tu peux aussi utiliser un Singleton.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, ce lien ou encore celui-ci[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
13 déc. 2011 à 08:17
Log1 comme une pseudo-factory, associée à une enum répertoriant les différents type de log/manière de logger


Je n'ai pas bien compris à quoi tu pense.

Peux-tu m'en dire plus.

Merci.
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
13 déc. 2011 à 08:19
tu peux aussi utiliser un Singleton.


Je n'ai que très peu de connaissance sur les Singleton mais il me semble q'un Singleton ne peux pas être hérité.
Peux-tu me donner un exemple de ton idée STP.

Merci
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
13 déc. 2011 à 21:53
Bonjour,

Un truc du genre :
public class ClsMere
{
private ClsMere()
{
}

public static ClsMere GetSingleton()
{
Return MonSingleton;
}
}

public class ClsEnfant:ClsMere
{
public static ClsEnfant GetSingleton()
{
Return MonSingletonEnfant;
}
}


Comme ça tu conserves les membres de ClsMere dans ClsEnfant avec 2 singletons.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, ce lien ou encore celui-ci[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Mon site
0
cs_vincnet68 Messages postés 100 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 24 mai 2013 1
16 déc. 2011 à 09:20
Merci pour ta proposition j'ai fait truc du même style (voir dessous).

Vincnet68
0
Rejoignez-nous