Sé una cadena en C# puede ser que aceptan valores null’, por el solo uso de null.

Sin embargo, el punto entero de tipos que aceptan valores null es que me llega la ayuda del compilador [editar : aka, tipo de error : no se puede agregar apple para el banano]

Y el uso de este tipo de sistema de hack-ish’ de ‘la nulabilidad depende del tipo subyacente’ rompe lo que garantiza que pueda tener (que no es poca cosa ya que parece ser el punto entero de la utilización de un tipo de sistema en el primer lugar..)

Lo son la forma estándar de lidiar con esto en C#, si uno quiere ?
Se me acaba de rodar mis propios valores null’ clase ?

Editar

Permítanme reformular la pregunta :

¿Cuál es la forma estándar, en C#, para asegurarse de que una variable que ha anotado como que aceptan valores null, no se asigna a una variable que no anotar como que aceptan valores null.

Que es :
¿cuál es la manera estándar de haber para todos los tipos de, precisamente lo que la ? palabras clave le da por tipo de valor.

  • No entiendo tu pregunta.
  • ¿Por qué el f# etiqueta?
  • ¿Qué problema específico está encontrando?
  • La pregunta es : ¿cómo tener un explícitamente tipo que acepta valores null, es decir, que el ompiler es consciente de que, a fin de que tengo una forma de no asignar por error un ‘no acepta valores null’ cadena a la que acepta valores null cadena.
  • ¿entiende usted de tipos que aceptan valores null ?
  • ¿? O, más apropiado, ¿realmente saben lo que usted quiere ser capaz de hacer que en la actualidad no, porque no tenemos idea de lo que estás pidiendo, basado en su pregunta. Tal vez usted podría proporcionar un código de ejemplo de lo que no está funcionando, por lo que podemos ayudarle a solucionar sus problemas.
  • porque esta es una de las molestias que uno no se en F#. Así que me imagino que la mayoría de los f# programador se han enfrentado a este.
  • Como se ha dicho, intento tener los valores null de anotación para cada tipo. así que si usted no entiende, por favor, consulte tipos que aceptan valores null.
  • no se que es terriblemente difícil acaba de rodar su propia cuenta, pero yo estaba pensando que la gente había dado algunas ideas para los pros y los contras de las diferentes opciones que yo podría no ver.
  • El que acepta valores null anotación es sólo valor para los tipos que no son ya que aceptan valores null, es decir, estructuras. No hay manera de solicitar la anotación a un tipo que ya es un tipo que acepta valores null. No es posible para usted para rodar su propio tipo que acepta valores null; al menos hasta el punto de que Nullable obras. De los múltiples aspectos de su funcionalidad requieren compilador de apoyo, para que su propia Nullable no puede nunca ser como los ricos de la característica.
  • Esta pregunta es probable que confundir a C# programadores no F# experiencia, porque los dos idiomas de la dirección de la nulabilidad de maneras muy diferentes. Si la pregunta se vuelve a abrir estaré encantado de publicar una respuesta.
  • En la mano, tengo un montón de DBNull.Valor, null, cadenas vacías, nullables, toda la definición de nulidad en el contexto de este programa de c#. muy interesante para trabajar con !
  • La pregunta ha sido re-abierto. Yo estaría interesado en su respuesta, porque creo que no es posible lograr esto. He publicado una respuesta a mí mismo explicando mis pensamientos.

InformationsquelleAutor nicolas | 2013-02-19

4 Comentarios

  1. 4

    Si usted se está preguntando acerca de una manera de asegurarse de que el tipo de retorno de un determinado método no es null, hay una solución:
    Ese método tiene que devolver un valor de tipo. Cada método que devuelve un tipo de referencia pueden devolver null. No hay nada que puedas hacer al respecto.

    Es así, usted podría crear un struct como esta, para ser capaz de devolver un valor de tipo:

    public struct SurelyNotNull<T>
    {
        private readonly T _value;
    
        public SurelyNotNull(T value)
        {
            if(value == null)
                throw new ArgumentNullException("value");
            _value = value;
        }
    
        public T Value
        {
            get { return _value; }
        }
    }

    Su método que, se supone, para devolver una cadena que ahora puede volver SurelyNotNull<string>.

    El problema con este enfoque es:

    No funciona. Mientras que el valor de retorno del método se garantiza que sea no null, el valor de retorno de SurelyNotNull<T>.Value no lo es. A primera vista, parece que está garantizado para ser no nulo. Pero puede ser, porque de esto:

    Cada estructura tiene una forma implícita, público, constructor sin parámetros, incluso cuando otro constructor se define.

    El siguiente código es válido y se compila con el struct desde arriba:

    new SurelyNotNull<string>();

    Conclusión:

    En C#, que son incapaces de conseguir lo que usted está tratando de hacer.

    Usted todavía puede utilizar este enfoque, usted sólo necesita comprender que alguien podría utilizar este tipo y aún así producir un valor nulo. A fallar rápido en este escenario, sería una buena idea añadir un cheque a la función de captador de Value y lanzar una excepción si _value es nulo.

    • Usted podría hacer la verificación null en el así. De esta manera, para que el mal null que no debería estar allí, no sería proliferado a través de un sistema y sería atrapado la primera vez que es tocada.
    • Interesante. Con un poco de convención en el código, que voy a hacer, supongo. Aunque no a prueba de balas, este seguro que es una mejora respecto a lo que existe en la actualidad es (una mezcla de muchas cosas), y puedo aprovechar el compilador para difundir la no nulidad.
    • Seguro. Pero que todavía sería una excepción en tiempo de ejecución y no un error el compilador puede detectar. Y eso es lo que es todo acerca de.
    • El compilador todavía no se puede demostrar que Value no se null, así que cuando usted está utilizando código estático damas como ReSharper o Código de Contratos aún así, usted recibirá un montón de «Posible uso de null» los mensajes.
    • Yo no diría que es todo acerca de tiempo de compilación. Sí, es bueno tener tiempo de compilación cheques, pero puede ser una gran mejora en el tiempo de ejecución para la captura accidental null temprano, en lugar de 3 minutos más tarde, cuando vaya a utilizarlo. Lo que realmente puede ayudar a la depuración.
    • por supuesto. Me refiero a que el compilador podría transmitir el tipo (nullableof T .. y no T !), y me gustaría ‘garantía’ con mi globo ocular con la retrospectiva que se aplica la convención en todas partes.
    • Estoy de acuerdo, no rápido es importante. Pero el tiempo de compilación es incluso más rápido que en tiempo de ejecución. Por lo tanto, si usted puede tener un error de tiempo de compilación que es preferible sobre una excepción de tiempo de ejecución, no importa que tan temprano que podría ocurrir.
    • Obviamente, yo no estaba tratando de hacer la declaración de que el tiempo de ejecución de la comprobación de errores es mejor que el tiempo de compilación de comprobación de error… La declaración era, simplemente, que no podría ser de valor añadido mediante la adición de la verificación null en la SurelyNotNull<T>.Value getter así.

  2. 2

    Como Daniel Hilgarth señaló, no hay ninguna prueba de balas para lograr esto. Mi propuesta es similar a la de él, pero con algunos añadidos de seguridad. Usted puede decidir por sí mismo si los beneficios superan el costo de la utilización de un tipo de contenedor a través de su programa.

    struct NonNull<T> where T : class {
        private readonly T _value;
        private readonly bool _isSafe;
    
        public NonNull(T value) {
            if (value == null)
                throw new ArgumentNullException();
            _value = value;
            _isSafe = true;
        }
        public T Value {
            get {
                if (_isSafe) return _value;
                throw new ArgumentNullException();
            }
        }
        public static implicit operator T(NonNull<T> nonNull) {
            return nonNull.Value;
        }
    }
    
    static class NonNull {
        public static NonNull<T> Create<T>(T value) where T : class {
            return new NonNull<T>(value);
        }
    }

    El tipo de contenedor es principalmente para hacer su intención de auto-documentación, por lo que es poco probable que prescindir de ella con un cero inicializa una estructura, pero que guarda una bandera para indicar que se ha inicializado correctamente, de todos modos. En que ciertamente inusual caso se producirá una ArgumentNullException al acceder al valor.

    class Program {
        static void Main(string[] args) {
            IsEmptyString(NonNull.Create("abc")); //false
            IsEmptyString(NonNull.Create("")); //true
            IsEmptyString(null); //won't compile
            IsEmptyString(NonNull.Create<string>(null)); //ArgumentNullException 
            IsEmptyString(new NonNull<string>()); //bypassing, still ArgumentNullException
        }
    
        static bool IsEmptyString(NonNull<string> s) {
            return StringComparer.Ordinal.Equals(s, "");
        }
    }

    Ahora, es mejor que un ocasional NRE? Tal vez. Se puede ahorrar un montón de repetitivo arg comprobación. Tendrás que decidir si vale la pena por su situación. Corto de compilador de apoyo, como F# proporciona, no hay manera de proporcionar en tiempo de compilación null seguridad, pero puede (podría decirse) facilidad de tiempo de ejecución de la seguridad.

    Puede que desee a votar este problema en el cliente de Microsoft del sitio de comentarios: Añadir que no aceptan valores null referencia a los tipos en C#

    • muy interesante ! me tranquilizo : usted tenía en el olvido durante mucho tiempo a la derecha ?
    • No he usado esto en el código de producción, pero sobre todo porque me he hecho la paz con este defecto en C# (y en muchos otros idiomas). F# dio un gran salto hacia adelante al abordar esta mil millones de dólares de error, aunque su intento fue limitada por la necesidad de la interoperabilidad. Todavía, usted puede crear algo de un valor null-caja de seguridad jardín amurallado para la mayoría de su código de F#.
    • Daniel, yo esperaba que usted tenía algo más en mente cuando has publicado tu comentario sobre la cuestión. Realmente creo que null es uno de los problemas más grandes en los lenguajes actuales. Acerca de su código: Tus implícito operador de T a NonNull quita mucho de la hora de compilar tipo de seguridad, ya que permite IsEmptyString(null) a compilar. Creo que sería mejor que no se la proporcionan.
    • Estás en lo correcto. Yo estaba tratando de hacer que sea fácil de usar y dispara por encima de mí. Me he quitado de ti.
    • Lo siento decepcionar. Yo tenía la misma idea en mente. Usted podría querer a voto de un problema relacionado en la Voz de Usuario (el enlace está en mi respuesta).
    • tendría que ser malo para agregar código para el tipo de valor a tener un tipo de uniforme ** private static bool IsValueType<S>(S obj) { return typeof(S).IsValueType; } public distinto de null(valor T) { if (!IsValueType(valor) && valor == null) throw new ArgumentNullException(); _value = valor; _isSafe = true; }**
    • value no puede ser un ValueType debido a la restricción where T : class. Además, este problema sólo se aplica a los tipos de referencia.
    • la persona que escribió la cita que mencionas es de 10 metros de distancia. grrrrr ….
    • Bien, puesto que él escribió quicksort usted puede dar a él su misericordia.
    • Upvoted.
    • No esta de comercio justo una excepción en tiempo de ejecución para el otro? Por favor alguien puede resaltar la ventaja aquí?

  3. 0

    Todos los tipos de referencia se aceptan valores null. La cadena es un tipo de referencia.

    • exactamente. así que me pregunto cómo hacer para que el compilador en cuenta explícitamente que este valor es potencialmente nullable por la construcción VS potencialmente nulo debido a un error
    • Si el tipo que se va a asignar a un tipo de referencia, a continuación, puede asignar el valor null. Si se trata de un struct (aparte de Nullable<T>, que ha compilador especial de apoyo), entonces usted no puede. Si usted tiene un método genérico y así, no sé el tipo, puede utilizar default(T) que será null para todos los tipos que aceptan valores null, o where T : class para asegurarse de que sólo los tipos de referencia son válidos argumentos genéricos.
    • si ser capaz de asignar a null es lo que está en juego para los chicos, entiendo por qué usted no consigue la pregunta.. El punto es aislar null, y la pista por donde puede ir, no gozan de la libertad de asignar null todo…
    • Así que usted está proponiendo que C# añade una característica del lenguaje para indicar que un tipo que acepta valores null? Si es así, este no es el lugar apropiado para tal solicitud, esto no es donde Microsoft va a buscar en función de las solicitudes de C#, y así que la pregunta está fuera de tema.
    • Estoy de acuerdo, sería muy bueno, si puede declarar los tipos de referencia como no que aceptan valores null. En la actualidad, toda referencia a los tipos que aceptan valores null, por lo que ninguna declaración especial que existe para decirle al compilador que aceptan valores null, porque todos ellos son.
    • Están preguntando por una característica del lenguaje, o no? Hasta ahora nadie tiene idea de lo que en realidad estamos pidiendo.
    • que no es una petición, es una pista de cómo usted probablemente debería mirar que aceptan valores null.
    • Usted realmente debe dejar de gastar su tiempo diciendo a todos que no saben de qué están hablando y pasar más tiempo tratando de explicar qué es lo que estás pidiendo. Insultar a la gente que está pidiendo ayuda acerca de que no es particularmente productivo.
    • exactamente, pero de alguna manera podría fingir, siguiendo la convención, por ejemplo, que yo sólo instancias Mynullable<T> y asegurarse de que cada asignación de valor se hace con los no-null referencias. por supuesto que no me garantiza nada en las fronteras, pero yo podría agregar algunas comprobaciones allí. siguiendo esta convención, me gustaría tener un compilador de verificación (Mynullable<T> no es asignable a partir de T), etc.. yo todavía podría tener un valor nulo Mynullable<T> pero al menos voy a deshacerse de algunos de la clase de los insectos, con esta semántica se comprueban en tiempo de compilación
    • no es un insulto, es realmente de cómo se debe mirar…
    • que parece el más ligero de enfoque, de hecho…
    • Por favor, consulte mi respuesta. Por desgracia, lo que no funciona bien.

Dejar respuesta

Please enter your comment!
Please enter your name here