What needs to be returned from function: null or empty object?



  • What is it? best practices upon return of data from function. Better return. null or an empty object? And why one option should be used compared to another.

    Consider the following:

    public UserEntity GetUserById(Guid userId)
    {
         //Здесь код доступа к базе данных...
    
     //Проверяем вернувшиеся данные и возвращаем null если ничего не найдено
     if (!DataExists)
        return null; 
        //Или же я должен вернуть пустой объект?
        //return new UserEntity();  
     else
        return existingUserEntity;
    

    }

    https://stackoverflow.com/q/1626597/5610621



  • Choice between null and a null-object depends on how the method will be used.

    Examples

    Receipt of user collection

    ICollection<User> GetAllUsers();
    

    How will this method be used? Probably like:

    foreach (User user in userService.GetAllUsers()) {
        // Обработка или отображение конкретного юзера
    }
    

    The return of an empty collection in this case will save us on one. if (sighs)foreach I can't ignore it. null) We don't care if there were any elements in the collection or not, the logic of the trigger method usually doesn't depend. If it's up to us, we can always use our properties. Count

    Receipt of one user

    User GetUser(int id);
    

    How will this method be used? Probably like:

    User user = userService.GetUser(id);
    if (user == null) {
        // Всё плохо, обработать ошибку
    }
    else {
        // Обработать или отобразить пользователя
    }
    

    In this case, it is reasonable to return nullbecause the existence and absence of the result implies different behaviours of the trigger code.

    What you're not supposed to do is come back. new User(): This will not allow a proper check, whether the requested user exists or not. If you do null objects, they should be in the only copy and non-replaceable if possible.

    Current user received

    User GetCurrentUser();
    

    How will this method be used? Probably like:

    User currentUser = userService.GetCurrentUser();
    Console.WriteLine("{0} ({1})", currentUser.Name, currentUser.Level);
    

    In this case, user treatment usually does not depend on the existence or absence of a real user, so the object ofground can be returned. In the case where verification is required, a characteristic of a type may be realized User.IsRegistered or User.AccessLevel

    Future plans

    In C# 7, a division between nullable and non-nullable for reference chips (in addition to value-types) is planned. Then the methods above will look like:

    ICollection<User> GetAllUsers();
    User? GetUser(int id); // Обратите внимание на знак вопроса
    User GetCurrentUser();
    

    If you call a method GetUser and not check the value nullthe compiler will give a warning.

    ReSharper

    If you have a R#, you can add annotations now:

    [NotNull, ItemNotNull]
    ICollection<User> GetAllUsers();
    [CanBeNull]
    User GetUser(int id);
    [NotNull]
    User GetCurrentUser();
    

    These annotations will allow the analyzer R# to clearly separate what might be nullwhich can't, and as a result, warn the user of potential errors.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2