.Net Best Practices: errori comuni introdotti da refactoring, incuria e neofiti

7

Quali sono i bug comuni introdotti da refactoring, incuria e neofiti?

Vorrei chiedere ai programmatori esperti di condividere la loro esperienza e elencare i bug che hanno usato per presentare quando erano inesperti.

Nella tua risposta, scrivi un titolo che menzioni il tipo di bug in grassetto , seguito da alcuni interruzioni di riga, quindi una spiegazione, la causa del bug e infine la correzione.

    
posta Nawaz 02.12.2010 - 18:46
fonte

3 risposte

3

Valori scritti manualmente anziché costanti

Esempio:

public District GetDefaultDistrict() {
  return GetById(1);
}

public IList<Revenue> GetRevenues() {
  return GetByCodes(new [] { 8010, 8011, 8096 });
}

e migliaia di utilizzo di 1, 8010, 8011 e 8096 in altri luoghi. Prova a immaginare se il distretto predefinito ora è 2 e 8011 spostato su 8012.

Fix:

public District GetDefaultDistrict() {
  return GetById(Consts.DEFAULT_DISTRICT_ID);
}

public IList<Revenue> GetRevenues() {
  return GetByCodes(Consts.REVENUE_CODES);
}

e usa queste costanti ovunque, dove è necessario determinare l'ID del distretto predefinito e / o altri valori statici.

O anche:

public IList<Revenue> GetRevenues() {
  var codes = GetRevenueCodes(); // get from db
  return GetByCodes(codes);
}

per ottenere valori effettivi da db. Ma questo è solo un esempio.

    
risposta data 02.12.2010 - 20:03
fonte
2

Differenza di proprietà / stringa vale a dire quando si utilizzano i quadri O / RM senza linq:

    Dim crit As DetachedCriteria
    crit = DetachedCriteria.For(GetType(RemitLineItemEntity), "remit")

    If Not String.IsNullOrEmpty(LastName) Then
        If LastName.Contains("%") Then
            crit = crit.Add(New LikeExpression("LastName", LastName))
            countCrit = countCrit.Add(New LikeExpression("LastName", LastName))
        Else
            crit = crit.Add(Expression.Eq("LastName", LastName))
            countCrit = countCrit.Add(Expression.Eq("LastName", LastName))
        End If

    End If

Quindi modifica la proprietà LastName dell'oggetto su SurName, o simile.

Fissare

Solo uno che conosco è quello di utilizzare uno strumento per fare refactoring (che la maggior parte fa). Dovrebbero anche prendere il nome del campo quotato, ma di solito usano la verifica umana su di esso (che porta all'errore umano).

    
risposta data 02.12.2010 - 18:54
fonte
1

Bug InotifyPropertyChanged introdotto da refactoring, errore ortografico, distinzione tra maiuscole e minuscole ecc.

A volte cambiamo il nome di alcune nostre proprietà e ci dimentichiamo di cambiare la "stringa" che passiamo al metodo OnPropertyChanged() ( soprattutto quando chiamiamo questo metodo da qualche altra parte ), oppure semplicemente ortografarlo, incluso caso-disallineamento.

Qualcosa del genere:

public string FirstName //earlier it was simply 'Name'
{
      get { return m_name; }
      set 
      { 
          m_name = value ;
          OnPropertyChanged("Name"); //still 'Name'. Bug!
         //or, OnPropertyChanged("FirstNane"); //changed, but misspelled. Bug!
      }
}

Fix

protected void OnPropertyChanged(string propertyName)
{
   //this raises exception if there is something wrong (only in debug mode!).
   RuntimeAssert.ValidatePropertyName(this, propertyName); 

   //your code here
}

Ecco l'implementazione della classe RuntimeAssert .

   public static class RuntimeAssert
    {
        private static Dictionary<Type, List<string>> ClassPropertyMap = new Dictionary<Type, List<string>>();
        private static List<string> GetProperties(Type type)
        {
            if (!ClassPropertyMap.ContainsKey(type))
            {
                PropertyInfo[] props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                ClassPropertyMap.Add(type, new List<string>(props.Where(p => true).Select(p => p.Name)));
            }
            return ClassPropertyMap[type];
        }
        [Conditional("DEBUG")]
        public static void ValidatePropertyName(object instance, string propertyName)
        {
            ValidatePropertyName(instance.GetType(), propertyName);
        }
        [Conditional("DEBUG")]
        public static void ValidatePropertyName(Type type, String propertyName)
        {
            List<string> properties = RuntimeAssert.GetProperties(type);
            if (!properties.Contains(propertyName))
            {
                string message = String.Format("Property '{0}' not found in class '{1}'", propertyName, type.FullName);
                throw new PropertyNotFoundException(message);
            }
        }
    }

E infine PropertyNotFoundException (è usato nella classe precedente).

public class PropertyNotFoundException : Exception
    {
        public PropertyNotFoundException(string message) : base(message) 
        {

        }
    }
    
risposta data 02.12.2010 - 18:48
fonte

Leggi altre domande sui tag