2009-07-21 19 views
5

więc mam klasy z jednego parametru ciągu w jego konstruktora:Co to jest poprawny sposób, aby potwierdzić argumenty konstruktora

public MyClass(string name) 
{ 
    this.Name = name; 
} 

ale nigdy nie chcesz się martwić o kogoś inicjalizacji instancji MojaKlasa z nazwą o wartości NULL lub łańcuchem o zerowej długości. Co jest najlepsze, aby sprawdzić poprawność parametru? Za pomocą właściwości lub metody zawsze możesz po prostu nic nie robić, zwracać wartość null lub niczego nie ustawiać, jeśli podano niepoprawny argument. Ale po wywołaniu konstruktora instancja obiektu jest już tworzona niezależnie od tego, czy została przekazana poprawna argumentacja.

Wyrzuca wyjątek, jak pokazano poniżej w najlepszy sposób? Czy jest jakaś inna metoda, która jest bardziej preferowana?

public MyClass(string name) 
{ 
    if (name == null | name == "") throw new ArgumentException("Name can not be null or blank", "name"); 

    this.Name = name; 
} 

Oczywiście zawsze mogłem ustawić nazwę do pewnego domyślnie jak „unnamed MojaKlasa”, jeśli argument jest nieważny, ale w tym przypadku wolałbym po prostu zapobiec nieprawidłową nazwę następnie próbuje założyć jakąś alternatywną zachowanie.

Odpowiedz

7
  1. rzucić ArgumentNullException
  2. dokument, który konstruktor zgłosi ArgumentNullException jeśli nazwa jest null
  3. Jeśli używasz Code Contracts, dodać Contract.EndContractBlock() wiersz po walidacji parametrów.

Edit: Zamiast tego:

if (name == null || name == "") 

Użyj tego:

if (string.IsNullOrEmpty(name)) 
+0

Należy być bardzo ostrożnym podczas rzucania wyjątków w konstruktorów Możecie skończyć z wycieku zasobów, gdy yo Zacząłeś chwytać zasoby/alokować pamięć itp. – Matt

+0

Tak czy inaczej, czyż nie byłby || (Logiczne OR), a nie | (Bitowy OR)? Zastanawiam się. –

+0

@Blaenk, tak, użyłem kopiowania i wklejania. Intuicyjnie moje użycie nie miało rzeczywistego wpływu na błąd OP. :) –

1

Możesz ustawić nazwę jako domyślną lub wyrzucić wyjątek. Coś innego jest po prostu błędne, ponieważ tworzy obiekt z nieważnym stanem.

1

Jeśli przechodzącą pustą lub null nazwę reprezentuje błąd, rzuca wyjątek to rozsądne posunięcie. Zignorowanie nazwy zerowej i wykonanie dowolnego odtwarzania jest maskowaniem błędu i może prowadzić do nieprawidłowego stanu.

Jeśli nie przekazanie nazwy jest prawidłowym sposobem na skonstruowanie obiektu, zaproponuj konstruktor bez parametrów.

3

Preferowanym rozwiązaniem jest wyrzucenie wyjątku. Nie wcześnie, często zawieść. Należy udokumentować, jakie poprawne parametry są dla konstruktora i czy są one niepoprawne.

Moim zdaniem, najważniejsze jest to, że nie chcesz po cichu wchłaniać awarii. Załóżmy, że użytkownik wpisał niepoprawnie nazwę (na przykład zostawił ją pustą). Lepiej, aby operacja zakończyła się niepowodzeniem i zwróć użytkownikowi powiadomienie, niż połknij niepowodzenie (z, powiedzmy, domyślnym) i niech użytkownik nie zauważy, że błędnie wpisał swój wpis.

Poprosiłem o podobną odpowiedź: question, aby załatwić kłótnię z niektórymi kolegami.

"Jednak po wywołaniu konstruktora instancja obiektu jest już tworzona niezależnie od tego, czy została przekazana poprawna argumentacja."

utworzeniu obiektu (czyli non-null) tylko wtedy, gdy konstruktor zwraca normalnie.

1

Jest Straż klasy narzędzie, które może okazać się przydatne do sprawdzania argumenty przekazywane do każdej metody.

Klasa jest avaialable here using system; użyciu System.Globalization;.

namespace Microsoft.Practices.Mobile.CompositeUI.Utility 
    { 
     /// <summary> 
     /// Common guard clauses. 
     /// </summary> 
     public static class Guard 
     { 


    /// <summary> 
     /// Checks a string argument to ensure it isn't null or empty. 
     /// </summary> 
     /// <param name="argumentValue">The argument value to check.</param> 
     /// <param name="argumentName">The name of the argument.</param> 
     public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName) 
     { 
      ArgumentNotNull(argumentValue, argumentName); 

      if (argumentValue.Trim().Length == 0) 
       throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.StringCannotBeEmpty, argumentName)); 
     } 

     /// <summary> 
     /// Checks an argument to ensure it isn't null. 
     /// </summary> 
     /// <param name="argumentValue">The argument value to check.</param> 
     /// <param name="argumentName">The name of the argument.</param> 
     public static void ArgumentNotNull(object argumentValue, string argumentName) 
     { 
      if (argumentValue == null) 
       throw new ArgumentNullException(argumentName); 
     } 

     /// <summary> 
     /// Checks an Enum argument to ensure that its value is defined by the specified Enum type. 
     /// </summary> 
     /// <param name="enumType">The Enum type the value should correspond to.</param> 
     /// <param name="value">The value to check for.</param> 
     /// <param name="argumentName">The name of the argument holding the value.</param> 
     public static void EnumValueIsDefined(Type enumType, object value, string argumentName) 
     { 
      if (Enum.IsDefined(enumType, value) == false) 
       throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, 
        Properties.Resources.InvalidEnumValue, 
        argumentName, enumType.ToString())); 
     } 

     /// <summary> 
     /// Verifies that an argument type is assignable from the provided type (meaning 
     /// interfaces are implemented, or classes exist in the base class hierarchy). 
     /// </summary> 
     /// <param name="assignee">The argument type.</param> 
     /// <param name="providedType">The type it must be assignable from.</param> 
     /// <param name="argumentName">The argument name.</param> 
     public static void TypeIsAssignableFromType(Type assignee, Type providedType, string argumentName) 
     { 
      if (!providedType.IsAssignableFrom(assignee)) 
       throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, 
        Properties.Resources.TypeNotCompatible, assignee, providedType), argumentName); 
     } 
    } 
} 
Powiązane problemy