2009-01-27 12 views
8

Tengo un método que nunca devuelve un objeto nulo. Quiero que quede claro para que los usuarios de mi API no tienen que escribir código como este:¿Cómo puedo demostrar que un método nunca devolverá nulo (diseño por contrato) en C#

if(Getxyz() != null) 
{ 
    // do stuff 
} 

¿Cómo puedo mostrar esta intención?

+0

Además, no hay manera de saber si podría devolver un objeto que no sea nulo en primer lugar (a menos que sea una estructura) ¿Quizás quiera devolver una estructura? – Trap

Respuesta

10

Unforutnately no hay manera integrada en C#

Se puede documentar este hecho, pero esto no se comprobará automáticamente.

Si está utilizando el reafilamiento, se puede configurar para comprobarlo correctamente cuando el método está marcado con un atributo [NotNull].

De lo contrario, puede utilizar la biblioteca Microsoft Contracts y agregar algo similar a lo siguiente a su método, pero esto es bastante verborrea adicional para una anotación tan simple.

Contract.Ensures(Contract.Result<string>() != null) 

SpeC# resolvió este problema al permitir a! después del tipo para marcarlo como un tipo no nulo, por ejemplo

string! foo 

pero SpeC# sólo puede ser utilizado para orientar .NET2, y ha sido usurpada por el Código contratos biblioteca.

+0

Uh, pero esto está mal ... puede garantizar que un método no devuelve nulo. Vea cualquiera de las otras respuestas ... –

+1

Usar una estructura no ayuda si quiere devolver una cadena que no sea nula. Podría devolver una estructura no nula que contenga una cadena que puede ser nula, pero ¿cómo es eso mejor? –

+0

la sintaxis es incorrecta en su ejemplo de Contratos. El 'Result' debe ser una llamada a método:' Contract.Result () ' – porges

6

A menos que esté utilizando un tipo basado en System.ValueType, creo que no tiene suerte. Probablemente sea mejor documentar esto claramente en el comentario de XML/metadatos para la función.

0

Puede incluir un método Debug.Assert(). Si bien esto ciertamente no hará cumplir la condición, debería dejar en claro (junto con la documentación) que un valor nulo no es aceptable.

2

No sé si hay una práctica recomendada para hacerlo desde una API, ya que seguiría programando a la defensiva y verificando si es nulo como consumidor. Creo que esta sigue siendo la mejor práctica en este caso, ya que tiendo a no querer confiar en que otro código siempre haga lo correcto.

0

Documéntelo y proporcione el código fuente.

1

Me gusta pensar que es al revés: si mi función puede devolver un valor nulo, es mejor asegurarse de que el usuario de la función lo sepa.

2

La única forma revisada de comprobar que un objeto C# nunca devuelve nulo es utilizar una estructura. Las estructuras pueden tener miembros que contengan valores nulos, pero nunca pueden ser nulos.

Todos los demás objetos C# pueden ser nulos.

código Ejemplo:

public struct StructExample 
{ 
    public string Val; 
} 

public class MyClass 
{ 
    private StructExamle example; 

    public MyClass() 
    { 
     example = null; // will give you a 'Cannot convert to null error 
    } 

    public StructExample GetXyz() 
    { 
     return null; // also gives the same error 
    } 
} 

El ejemplo anterior no se compilará. Si el uso de una estructura es aceptable (se convierte en un tipo de valor, se pasa en la pila, no se puede subclasificar), entonces esto podría funcionar para usted.

+0

Tenga en cuenta que las estructuras pasan * por valor * de forma predeterminada, mientras que las clases pasan * por ref * de forma predeterminada. La diferencia es que los * contenidos * de la estructura se vuelcan en la pila al pasar, mientras que para las clases solo se arroja una * referencia * en la pila, lo que le permite interactuar con el objeto original en lugar de una copia nueva. Esto puede ser anulado usando la palabra clave "ref", pero luego 1) tiene que recordar usarlo en cada lugar donde no quiere una copia, y 2) puede volver a ser nulo, que era lo que intentaba evitar en primer lugar. – Thought

Cuestiones relacionadas