¿Es mejor devolver la colección nula o vacía?


Esa es una especie de pregunta general (pero estoy usando C#), ¿cuál es la mejor manera (mejor práctica), devuelve una colección nula o vacía para un método que tiene una colección como tipo de retorno ?

Author: Mark Bell, 2009-12-28

18 answers

Colección Vacía. Siempre.

Esto apesta:

if(myInstance.CollectionProperty != null)
{
  foreach(var item in myInstance.CollectionProperty)
    /* arrgh */
}

Se considera una buena práctica NO devolver NUNCA null al devolver una colección o enumerable. SIEMPRE devuelve un enumerable/collection vacío. Evita las tonterías mencionadas anteriormente, y evita que su automóvil sea egged por compañeros de trabajo y usuarios de sus clases.

Al hablar de propiedades, establezca siempre su propiedad una vez y olvídela

public List<Foo> Foos {public get; private set;}

public Bar() { Foos = new List<Foo>(); }

En. NET 4.6.1, puede condensar esto bastante mucho:

public List<Foo> Foos { get; } = new List<Foo>();

Cuando se habla de métodos que devuelven enumerables, puede devolver fácilmente un enumerable vacío en lugar de null...

public IEnumerable<Foo> GetMyFoos()
{
  return InnerGetFoos() ?? Enumerable.Empty<Foo>();
}

Utilizando Enumerable.Empty<T>() puede ser visto como más eficiente que devolver, por ejemplo, una nueva colección vacía o matriz.

 435
Author: Will,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-18 20:54:38

Del Framework Design Guidelines 2nd Edition (pg. 256):

NO devuelve valores nulos desde propiedades de colección o de métodos devolución de colecciones. Devolver un vacío colección o una matriz vacía en su lugar.

Aquí hay otro artículo interesante sobre los beneficios de no devolver los nulos (estaba tratando de encontrar algo en el blog de Brad Abram, y enlazó al artículo).

Edit - como Eric Lippert ha comentado ahora a la pregunta original, también me gustaría enlazar a su excelente artículo.

 144
Author: RichardOD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-04 04:41:58

Depende de su contrato y su caso concreto. Generalmente es mejor devolver colecciones vacías, pero a veces (rara vez):

  • null podría significar algo más específico;
  • su API (contrato) podría obligarle a devolver null.

Algunos ejemplos concretos:

  • un componente de interfaz de usuario (de una biblioteca fuera de su control), podría estar renderizando una tabla vacía si se pasa una colección vacía, o todos, si se pasa null.
  • en un Object-to-XML (JSON/whatever), donde null significaría que falta el elemento, mientras que una colección vacía haría que un <collection />
  • está utilizando o implementando una API que indica explícitamente que debe devolver/pasar null{[16]]}
 84
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-08 11:46:43

Hay otro punto que aún no se ha mencionado. Considere el siguiente código:

    public static IEnumerable<string> GetFavoriteEmoSongs()
    {
        yield break;
    }

El lenguaje C# devolverá un enumerador vacío cuando llame a este método. Por lo tanto, para ser consistente con el diseño del lenguaje (y, por lo tanto, con las expectativas del programador) se debe devolver una colección vacía.

 33
Author: Jeffrey L Whitledge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 16:19:15

Vacío es mucho más amigable para el consumidor.

Hay un método claro para hacer un enumerable vacío:

Enumerable.Empty<Element>()
 29
Author: George Polevoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-30 14:28:42

Me parece que debe devolver el valor que es semánticamente correcto en contexto, cualquiera que sea. Una regla que dice "siempre devolver una colección vacía" me parece un poco simplista.

Supongamos que en, digamos, un sistema para un hospital, tenemos una función que se supone que devuelve una lista de todas las hospitalizaciones previas de los últimos 5 años. Si el cliente no ha estado en el hospital, tiene sentido devolver una lista vacía. Pero ¿qué pasa si el cliente dejó esa parte de ¿el formulario de admisión en blanco? Necesitamos un valor diferente para distinguir " lista vacía "de" sin respuesta "o"no sé". Podríamos lanzar una excepción, pero no es necesariamente una condición de error, y no necesariamente nos conduce fuera del flujo normal del programa.

A menudo me he sentido frustrado por sistemas que no pueden distinguir entre cero y ninguna respuesta. He tenido un número de veces donde un sistema me ha pedido que ingrese algún número, introduzco cero, y recibo un mensaje de error que me dice que debo introduzca un valor en este campo. Acabo de hacerlo: ¡Entré en cero! Pero no aceptará cero porque no puede distinguirlo de ninguna respuesta.


Respuesta a Saunders:

Sí, asumo que hay una diferencia entre "La persona no respondió a la pregunta" y "La respuesta fue cero."Ese fue el punto del último párrafo de mi respuesta. Muchos programas son incapaces de distinguir "no sé" de blanco o cero, lo que me parece un defecto potencialmente grave. Por ejemplo, yo era comprando una casa hace más o menos un año. Fui a un sitio web de bienes raíces y había muchas casas listadas con un precio de venta de 0 0. Sonaba bastante bien para mí: ¡Están regalando estas casas! Pero estoy seguro de que la triste realidad era que simplemente no habían entrado en el precio. En ese caso puedes decir, "Bueno, OBVIAMENTE cero significa que no entraron en el precio nobody nadie va a regalar una casa gratis."Pero el sitio también enumeró los precios promedio de venta y venta de casas en varios ciudad. No puedo evitar preguntarme si el promedio no incluyó los ceros, lo que da un promedio incorrectamente bajo para algunos lugares. es decir, ¿cuál es el promedio de 100.000$; $120,000; y "no sé"? Técnicamente, la respuesta es "no sé". Lo que probablemente realmente queremos ver son 1 110.000. Pero lo que probablemente obtendremos es 7 73.333, lo que sería completamente erróneo. Además, ¿y si tuviéramos este problema en un sitio donde los usuarios pueden ordenar en línea? (Poco probable para bienes raíces, pero estoy seguro de que lo has visto hecho para muchos otros productos.) ¿Realmente querríamos que" precio no especificado todavía "se interpretara como"libre"?

RE tener dos funciones separadas, un "¿hay alguna?"y an" si es así, ¿qué es?"Sí, ciertamente podrías hacer eso, pero ¿por qué querrías hacerlo? Ahora el programa que llama debe hacer dos llamadas en vez de una. ¿Qué sucede si un programador no llama al "any"?"y va directamente al" ¿qué es?" ? ¿El programa devolverá un cero erróneo? Lanzar una excepción? Devolver un valor indefinido? Crea más código, más trabajo y más errores potenciales.

El único beneficio que veo es que le permite cumplir con una regla arbitraria. ¿Hay alguna ventaja en esta regla que haga que valga la pena la molestia de obedecerla? Si no, ¿por qué molestarse?


Responder a Jammycakes:

Considere cómo se vería el código real. Sé que la pregunta decía C# pero discúlpame si escribo Java. Mi C# no es muy agudo y el principio es el mismo.

Con un valor nulo retorno:

HospList list=patient.getHospitalizationList(patientId);
if (list==null)
{
   // ... handle missing list ...
}
else
{
  for (HospEntry entry : list)
   //  ... do whatever ...
}

Con una función separada:

if (patient.hasHospitalizationList(patientId))
{
   // ... handle missing list ...
}
else
{
  HospList=patient.getHospitalizationList(patientId))
  for (HospEntry entry : list)
   // ... do whatever ...
}

En realidad es una línea o dos menos código con el retorno nulo, por lo que no es más carga para el llamante, es menos.

No veo cómo crea un problema SECO. No es que tengamos que ejecutar la llamada dos veces. Si siempre queríamos hacer lo mismo cuando la lista no existe, tal vez podríamos empujar el manejo hacia abajo a la función get-list en lugar de hacer que el llamador lo haga, y así poner el código en el llamador sería un Violación seca. Pero casi seguramente no queremos hacer siempre lo mismo. En las funciones donde debemos tener la lista a procesar, una lista faltante es un error que bien podría detener el procesamiento. Pero en una pantalla de edición, seguramente no queremos detener el procesamiento si aún no han ingresado datos: queremos permitirles ingresar datos. Por lo tanto, el manejo de "sin lista" debe hacerse en el nivel de llamada de una manera u otra. Y si lo hacemos con un retorno nulo o una función separada no hace diferencia a la más grande principio.

Claro, si la persona que llama no comprueba null, el programa podría fallar con una excepción de puntero nulo. Pero si hay una función separada "got any" y la persona que llama no llama a esa función sino que llama ciegamente a la función "get list", ¿qué sucede? Si se produce una excepción o no, bueno, eso es más o menos lo mismo que lo que pasaría si se devuelve null y no comprobarlo. Si devuelve una lista vacía, eso está mal. Estás fallando en distinguir entre "tengo una lista con cero elementos" y "no tengo una lista". Es como devolver cero por el precio cuando el usuario no introdujo ningún precio: simplemente está mal.

No veo cómo ayuda adjuntar un atributo adicional a la colección. La persona que llama todavía tiene que comprobarlo. ¿Cómo es eso mejor que comprobar null? Una vez más, lo peor que podría pasar es que el programador se olvide de comprobarlo, y dar resultados incorrectos.

Una función que devuelve null no es un sorpréndase si el programador está familiarizado con el concepto de nulo significado "no tiene valor", que creo que cualquier programador competente debería haber oído hablar, ya sea que piense que es una buena idea o no. Creo que tener una función separada es más un problema de" sorpresa". Si un programador no está familiarizado con la API, cuando ejecuta una prueba sin datos, descubrirá rápidamente que a veces obtiene un null. Pero, ¿cómo descubriría la existencia de otra función a menos que se le ocurriera que podría ser una función y comprueba la documentación y la documentación está completa y comprensible? Preferiría tener una función que siempre me da una respuesta significativa, en lugar de dos funciones que tengo que conocer y recordar llamar a ambas.

 18
Author: Jay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-21 06:41:17

Si una colección vacía tiene sentido semánticamente, eso es lo que prefiero devolver. Devolver una colección vacía para GetMessagesInMyInbox() comunica que "realmente no tiene ningún mensaje en su bandeja de entrada", mientras que devolver null podría ser útil para comunicar que no hay datos suficientes disponibles para decir cómo debe ser la lista que podría ser devuelta.

 10
Author: David Hedlund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:35:12

Devolver null podría ser más eficiente, ya que no se crea ningún objeto nuevo. Sin embargo, a menudo también requeriría una verificación null (o manejo de excepciones.)

Semánticamente, null y una lista vacía no significan lo mismo. Las diferencias son sutiles y una opción puede ser mejor que la otra en casos específicos.

Independientemente de su elección, documéntelo para evitar confusiones.

 6
Author: Karmic Coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:39:17

Se podría argumentar que el razonamiento detrás de Null Object Pattern es similar a uno a favor de devolver la colección vacía.

 6
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 16:28:18

Depende de la situación. Si es un caso especial, devuelve null. Si la función simplemente devuelve una colección vacía, entonces obviamente devolver eso está bien. Sin embargo, devolver una colección vacía como un caso especial debido a parámetros inválidos u otras razones NO es una buena idea, porque está enmascarando una condición de caso especial.

En realidad, en este caso generalmente prefiero lanzar una excepción para asegurarme de que realmente no se ignore :)

Diciendo que hace que el código más robusto (devolviendo una colección vacía) ya que no tienen que manejar la condición nula es malo, ya que es simplemente enmascarar un problema que debe ser manejado por el código de llamada.

 4
Author: Larry Watanabe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:46:21

Yo diría que null no es lo mismo que una colección vacía y usted debe elegir cuál representa mejor lo que está devolviendo. En la mayoría de los casos null no es nada (excepto en SQL). Una colección vacía es algo, aunque algo vacío.

Si usted tiene que elegir uno u otro, yo diría que usted debe tender hacia una colección vacía en lugar de null. Pero hay momentos en que una colección vacía no es lo mismo que un valor nulo.

 4
Author: Jason Baker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:48:28

Piensa siempre a favor de tus clientes (que están usando tu api):

Devolver 'null' a menudo causa problemas con los clientes que no manejan las comprobaciones null correctamente, lo que causa una excepción NullPointerException durante el tiempo de ejecución. He visto casos en los que una comprobación nula que falta forzó un problema de producción de prioridad (un cliente usó foreach(...) en un valor nulo). Durante las pruebas, el problema no se produjo, porque los datos operados eran ligeramente diferentes.

 4
Author: manuel aldana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 20:39:33

Me gusta dar explicaciones aquí, con un ejemplo adecuado.

Considere un caso aquí..

int totalValue = MySession.ListCustomerAccounts()
                          .FindAll(ac => ac.AccountHead.AccountHeadID 
                                         == accountHead.AccountHeadID)
                          .Sum(account => account.AccountValue);

Aquí considere las funciones que estoy usando ..

1. ListCustomerAccounts() // User Defined
2. FindAll()              // Pre-defined Library Function

Puedo usar fácilmente ListCustomerAccount y FindAll en lugar de.,

int totalValue = 0; 
List<CustomerAccounts> custAccounts = ListCustomerAccounts();
if(custAccounts !=null ){
  List<CustomerAccounts> custAccountsFiltered = 
        custAccounts.FindAll(ac => ac.AccountHead.AccountHeadID 
                                   == accountHead.AccountHeadID );
   if(custAccountsFiltered != null)
      totalValue = custAccountsFiltered.Sum(account => 
                                            account.AccountValue).ToString();
}

NOTA: Dado que AccountValue no es null, la función Sum() no return null. Por lo tanto, puedo usarlo directamente.

 3
Author: Muthu Ganapathy Nathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-21 06:38:51

Tuvimos esta discusión entre el equipo de desarrollo en el trabajo hace una semana más o menos, y casi unánimemente fuimos por la colección vacía. Una persona quería devolver null por la misma razón que Mike especificó anteriormente.

 2
Author: Henric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:35:36

Colección Vacía. Si está utilizando C#, la suposición es que maximizar los recursos del sistema no es esencial. Aunque menos eficiente, devolver la Colección vacía es mucho más conveniente para los programadores involucrados (por la razón que se describió anteriormente).

 2
Author: mothis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-28 15:39:59

Devolver una colección vacía es mejor en la mayoría de los casos.

La razón de esto es la conveniencia de la implementación del llamante, el contrato consistente y la implementación más fácil.

Si un método devuelve null para indicar un resultado vacío, el llamante debe implementar un adaptador de comprobación de null además de la enumeración. Este código se duplica en varios llamantes, así que por qué no poner este adaptador dentro del método para que pueda ser reutilizado.

Un uso válido de null paraerableumerable podría ser una indicación de ausencia de resultado, o un fallo de la operación, pero en este caso se deben considerar otras técnicas, como lanzar una excepción.

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace StackOverflow.EmptyCollectionUsageTests.Tests
{
    /// <summary>
    /// Demonstrates different approaches for empty collection results.
    /// </summary>
    class Container
    {
        /// <summary>
        /// Elements list.
        /// Not initialized to an empty collection here for the purpose of demonstration of usage along with <see cref="Populate"/> method.
        /// </summary>
        private List<Element> elements;

        /// <summary>
        /// Gets elements if any
        /// </summary>
        /// <returns>Returns elements or empty collection.</returns>
        public IEnumerable<Element> GetElements()
        {
            return elements ?? Enumerable.Empty<Element>();
        }

        /// <summary>
        /// Initializes the container with some results, if any.
        /// </summary>
        public void Populate()
        {
            elements = new List<Element>();
        }

        /// <summary>
        /// Gets elements. Throws <see cref="InvalidOperationException"/> if not populated.
        /// </summary>
        /// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>.</returns>
        public IEnumerable<Element> GetElementsStrict()
        {
            if (elements == null)
            {
                throw new InvalidOperationException("You must call Populate before calling this method.");
            }

            return elements;
        }

        /// <summary>
        /// Gets elements, empty collection or nothing.
        /// </summary>
        /// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>, with zero or more elements, or null in some cases.</returns>
        public IEnumerable<Element> GetElementsInconvenientCareless()
        {
            return elements;
        }

        /// <summary>
        /// Gets elements or nothing.
        /// </summary>
        /// <returns>Returns <see cref="IEnumerable{T}"/> of <see cref="Element"/>, with elements, or null in case of empty collection.</returns>
        /// <remarks>We are lucky that elements is a List, otherwise enumeration would be needed.</remarks>
        public IEnumerable<Element> GetElementsInconvenientCarefull()
        {
            if (elements == null || elements.Count == 0)
            {
                return null;
            }
            return elements;
        }
    }

    class Element
    {
    }

    /// <summary>
    /// http://stackoverflow.com/questions/1969993/is-it-better-to-return-null-or-empty-collection/
    /// </summary>
    class EmptyCollectionTests
    {
        private Container container;

        [SetUp]
        public void SetUp()
        {
            container = new Container();
        }

        /// <summary>
        /// Forgiving contract - caller does not have to implement null check in addition to enumeration.
        /// </summary>
        [Test]
        public void UseGetElements()
        {
            Assert.AreEqual(0, container.GetElements().Count());
        }

        /// <summary>
        /// Forget to <see cref="Container.Populate"/> and use strict method.
        /// </summary>
        [Test]
        [ExpectedException(typeof(InvalidOperationException))]
        public void WrongUseOfStrictContract()
        {
            container.GetElementsStrict().Count();
        }

        /// <summary>
        /// Call <see cref="Container.Populate"/> and use strict method.
        /// </summary>
        [Test]
        public void CorrectUsaOfStrictContract()
        {
            container.Populate();
            Assert.AreEqual(0, container.GetElementsStrict().Count());
        }

        /// <summary>
        /// Inconvenient contract - needs a local variable.
        /// </summary>
        [Test]
        public void CarefulUseOfCarelessMethod()
        {
            var elements = container.GetElementsInconvenientCareless();
            Assert.AreEqual(0, elements == null ? 0 : elements.Count());
        }

        /// <summary>
        /// Inconvenient contract - duplicate call in order to use in context of an single expression.
        /// </summary>
        [Test]
        public void LameCarefulUseOfCarelessMethod()
        {
            Assert.AreEqual(0, container.GetElementsInconvenientCareless() == null ? 0 : container.GetElementsInconvenientCareless().Count());
        }

        [Test]
        public void LuckyCarelessUseOfCarelessMethod()
        {
            // INIT
            var praySomeoneCalledPopulateBefore = (Action)(()=>container.Populate());
            praySomeoneCalledPopulateBefore();

            // ACT //ASSERT
            Assert.AreEqual(0, container.GetElementsInconvenientCareless().Count());
        }

        /// <summary>
        /// Excercise <see cref="ArgumentNullException"/> because of null passed to <see cref="Enumerable.Count{TSource}(System.Collections.Generic.IEnumerable{TSource})"/>
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void UnfortunateCarelessUseOfCarelessMethod()
        {
            Assert.AreEqual(0, container.GetElementsInconvenientCareless().Count());
        }

        /// <summary>
        /// Demonstrates the client code flow relying on returning null for empty collection.
        /// Exception is due to <see cref="Enumerable.First{TSource}(System.Collections.Generic.IEnumerable{TSource})"/> on an empty collection.
        /// </summary>
        [Test]
        [ExpectedException(typeof(InvalidOperationException))]
        public void UnfortunateEducatedUseOfCarelessMethod()
        {
            container.Populate();
            var elements = container.GetElementsInconvenientCareless();
            if (elements == null)
            {
                Assert.Inconclusive();
            }
            Assert.IsNotNull(elements.First());
        }

        /// <summary>
        /// Demonstrates the client code is bloated a bit, to compensate for implementation 'cleverness'.
        /// We can throw away the nullness result, because we don't know if the operation succeeded or not anyway.
        /// We are unfortunate to create a new instance of an empty collection.
        /// We might have already had one inside the implementation,
        /// but it have been discarded then in an effort to return null for empty collection.
        /// </summary>
        [Test]
        public void EducatedUseOfCarefullMethod()
        {
            Assert.AreEqual(0, (container.GetElementsInconvenientCarefull() ?? Enumerable.Empty<Element>()).Count());
        }
    }
}
 2
Author: George Polevoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-25 11:46:32

Lo llamo mi billón de dólares mistake...At esa vez, estaba diseñando el primer sistema de tipos completo para referencias en un lenguaje orientado a objetos. Mi objetivo era asegurar que todo el uso de referencias fuera absolutamente seguro, con la comprobación realizada automáticamente por el compilador. Pero no pude resistir la tentación de poner una referencia nula, simplemente porque era tan fácil de implementar. Esto ha llevado a innumerables errores, vulnerabilidades y bloqueos del sistema, que probablemente causó mil millones de dólares de dolor y daños en los últimos cuarenta años. - Tony Hoare, inventor de ALGOL W.

Ver aquí para una elaborada tormenta de mierda sobre null en general. No estoy de acuerdo con la afirmación de que undefined es otro null, pero todavía vale la pena leer. Y explica, por qué debe evitar null en absoluto y no solo en el caso de que haya pedido. La esencia es, que null es en cualquier idioma un caso especial. Tienes que pensar en null como un salvedad. undefined es diferente de esa manera, ese código que trata con un comportamiento indefinido es en la mayoría de los casos solo un error. C y la mayoría de los otros lenguajes también tienen un comportamiento indefinido, pero la mayoría de ellos no tienen un identificador para eso en el lenguaje.

 2
Author: ceving,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-04 16:27:09

Desde la perspectiva de la gestión de la complejidad, un objetivo principal de la ingeniería de software, queremos evitar propagar complejidad ciclomática innecesaria a los clientes de una API. Devolver un null al cliente es como devolverles el coste de complejidad ciclomática de otra rama de código.

(Esto corresponde a una carga de pruebas unitarias. Tendría que escribir una prueba para el caso de retorno nulo, además del caso de retorno de colección vacía.)

 1
Author: dthal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 18:03:18