Estimados visitantes futuros, las respuestas a esta pregunta se aplican igualmente a una excepción ArgumentNullException . Si su pregunta se ha cerrado como un duplicado de esta y está experimentando un ANE, siga las instrucciones en las respuestas para depurar y solucionar su problema.
@ ANE solo debería suceder si se pasa un valor nulo como parámetro. ¿Puede dar un ejemplo si una pregunta ANE se cierra como un duplicado de esta?
John Saunders
Surgió en Meta, pero tendría que ir a buscar el enlace. Pero en cuanto a ese comentario, un ANE es simplemente un NRE, pero alguien agregó una verificación preventiva, y al menos sabe exactamente qué es nulo (se proporciona el nombre del argumento), por lo que es un poco más fácil de diagnosticar que un NRE directo.
Respuestas:
2416
¿Cual es la causa?
Línea de fondo
Está intentando usar algo que es null(o Nothingen VB.NET). Esto significa que lo configuró nullo nunca lo configuró para nada.
Como cualquier otra cosa, nullse pasa. Si es nullen el método "A", podría ser que el método "B" pasó una nullde método "A".
null puede tener diferentes significados:
Variables de objeto que no están inicializadas y, por lo tanto, no apuntan a nada. En este caso, si accede a las propiedades o métodos de dichos objetos, provoca a NullReferenceException.
El desarrollador está utilizando nullintencionalmente para indicar que no hay un valor significativo disponible. Tenga en cuenta que C # tiene el concepto de tipos de datos anulables para variables (como las tablas de la base de datos pueden tener campos anulables); puede asignarlos nullpara indicar que no hay ningún valor almacenado en él, por ejemplo, int? a = null;donde el signo de interrogación indica que está permitido almacenar nulo en variable a. Puede verificar eso con if (a.HasValue) {...}o con if (a==null) {...}. Las variables anulables, como aeste ejemplo, permiten acceder al valor a través de forma a.Valueexplícita, o de manera normal a través de a. Tenga en cuenta que acceder a él a través de a.Valuearroja un en InvalidOperationExceptionlugar de un NullReferenceExceptionif aesnull- debe hacer la verificación de antemano, es decir, si tiene otra variable anulable int b;, debe hacer asignaciones como if (a.HasValue) { b = a.Value; }o más cortas if (a != null) { b = a; }.
El resto de este artículo entra en más detalles y muestra errores que muchos programadores a menudo cometen y que pueden conducir a una NullReferenceException.
Más específicamente
La runtimelanzar una NullReferenceExceptionsiempre significa lo mismo: usted está tratando de utilizar una referencia, y la referencia no se ha inicializado (o fue una vez inicializado, sino que está ya no inicializado).
Esto significa que la referencia es null, y no puede acceder a los miembros (como los métodos) a través de una nullreferencia. El caso más simple:
string foo =null;
foo.ToUpper();
Esto arrojará un NullReferenceExceptionen la segunda línea porque no puede llamar al método de instancia ToUpper()en una stringreferencia que apunta null.
Depuración
¿Cómo encuentras la fuente de un NullReferenceException? Además de mirar la excepción en sí, que se lanzará exactamente en el lugar donde ocurre, se aplican las reglas generales de depuración en Visual Studio: coloque puntos de interrupción estratégicos e inspeccione sus variables , ya sea colocando el mouse sobre sus nombres, abriendo un ( Rápido) Mire la ventana o use los diversos paneles de depuración como Locales y Autos.
Si desea averiguar dónde se establece o no la referencia, haga clic con el botón derecho en su nombre y seleccione "Buscar todas las referencias". Luego puede colocar un punto de interrupción en cada ubicación encontrada y ejecutar su programa con el depurador adjunto. Cada vez que el depurador se interrumpe en dicho punto de interrupción, debe determinar si espera que la referencia no sea nula, inspeccionar la variable y verificar que apunta a una instancia cuando lo espera.
Siguiendo el flujo del programa de esta manera, puede encontrar la ubicación donde la instancia no debe ser nula y por qué no está configurada correctamente.
Ejemplos
Algunos escenarios comunes donde se puede lanzar la excepción:
Genérico
ref1.ref2.ref3.member
Si ref1 o ref2 o ref3 es nulo, obtendrá un NullReferenceException. Si desea resolver el problema, descubra cuál es nulo reescribiendo la expresión a su equivalente más simple:
Específicamente, en HttpContext.Current.User.Identity.Name, HttpContext.Currentpodría ser nulo, o la Userpropiedad podría ser nula, o la Identitypropiedad podría ser nula.
Indirecto
publicclassPerson{publicintAge{get;set;}}publicclassBook{publicPersonAuthor{get;set;}}publicclassExample{publicvoidFoo(){Book b1 =newBook();int authorAge = b1.Author.Age;// You never initialized the Author property.// there is no Person to get an Age from.}}
Si desea evitar la referencia nula secundaria (Persona), puede inicializarla en el constructor del objeto primario (Libro).
Inicializadores de objetos anidados
Lo mismo se aplica a los inicializadores de objetos anidados:
Book b1 =newBook{Author={Age=45}};
Esto se traduce en
Book b1 =newBook();
b1.Author.Age=45;
Mientras newse usa la palabra clave, solo crea una nueva instancia de Book, pero no una nueva instancia de Person, por lo que Authorla propiedad sigue siendo null.
La colección anidada se Initializerscomporta igual:
Person p1 =newPerson{Books={newBook{Title="Title1"},newBook{Title="Title2"},}};
Esto se traduce en
Person p1 =newPerson();
p1.Books.Add(newBook{Title="Title1"});
p1.Books.Add(newBook{Title="Title2"});
El new Personúnico crea una instancia de Person, pero la Bookscolección sigue siendo null. La Initializersintaxis de la colección no crea una colección p1.Books, solo se traduce en las p1.Books.Add(...)declaraciones.
Formación
int[] numbers =null;int n = numbers[0];// numbers is null. There is no array to index.
Elementos de matriz
Person[] people =newPerson[5];
people[0].Age=20// people[0] is null. The array was allocated but not// initialized. There is no Person to set the Age for.
Matrices Dentadas
long[][] array =newlong[1][];
array[0][0]=3;// is null because only the first dimension is yet initialized.// Use array[0] = new long[2]; first.
Colección / Lista / Diccionario
Dictionary<string,int> agesForNames =null;int age = agesForNames["Bob"];// agesForNames is null.// There is no Dictionary to perform the lookup.
Rango Variable (indirecto / diferido)
publicclassPerson{publicstringName{get;set;}}var people =newList<Person>();
people.Add(null);var names =from p in people select p.Name;string firstName = names.First();// Exception is thrown here, but actually occurs// on the line above. "p" is null because the// first element we added to the list is null.
Eventos
publicclassDemo{publiceventEventHandlerStateChanged;protectedvirtualvoidOnStateChanged(EventArgs e){StateChanged(this, e);// Exception is thrown here // if no event handlers have been attached// to StateChanged event}}###Bad Naming Conventions:If you named fields differently from locals, you might have realized that you never initialized the field.
Esto se puede resolver siguiendo la convención para prefijar campos con un guión bajo:
privateCustomer _customer;
Ciclo de vida de la página ASP.NET:
publicpartialclassIssues_Edit:System.Web.UI.Page{protectedTestIssue myIssue;protectedvoidPage_Load(object sender,EventArgs e){if(!IsPostBack){// Only called on first load, not when button clicked
myIssue =newTestIssue();}}protectedvoidSaveButton_Click(object sender,EventArgs e){
myIssue.Entry="NullReferenceException here!";}}
Valores de sesión ASP.NET
// if the "FirstName" session value has not yet been set,// then this line will throw a NullReferenceExceptionstring firstName =Session["FirstName"].ToString();
Modelos de vista vacía ASP.NET MVC
Si la excepción ocurre cuando se hace referencia a una propiedad de @Modelen un ASP.NET MVC View, debe comprender que Modelse establece en su método de acción, cuando returnve. Cuando devuelve un modelo vacío (o propiedad de modelo) desde su controlador, la excepción ocurre cuando las vistas acceden a él:
// ControllerpublicclassRestaurant:Controller{publicActionResultSearch(){returnView();// Forgot the provide a Model here.}}// Razor view @foreach(var restaurantSearch inModel.RestaurantSearch)// Throws.{}<p>@Model.somePropertyName</p><!--Alsothrows-->
Orden de creación de control de WPF y eventos
WPFLos controles se crean durante la llamada a InitializeComponenten el orden en que aparecen en el árbol visual. A se NullReferenceExceptiongenerará en el caso de controles creados con controladores de eventos, etc., que se activan durante los InitializeComponentcuales se hace referencia a los controles creados tarde.
Por ejemplo :
<Grid><!-- Combobox declared first --><ComboBoxName="comboBox1"Margin="10"SelectedIndex="0"SelectionChanged="comboBox1_SelectionChanged"><ComboBoxItemContent="Item 1"/><ComboBoxItemContent="Item 2"/><ComboBoxItemContent="Item 3"/></ComboBox><!-- Label declared later --><LabelName="label1"Content="Label"Margin="10"/></Grid>
Aquí comboBox1se crea antes label1. Si comboBox1_SelectionChangedintenta hacer referencia a `label1, aún no se habrá creado.
Cambiar el orden de las declaraciones en el XAML(es decir, enumerar label1antes comboBox1, ignorar los problemas de la filosofía del diseño, al menos resolvería NullReferenceExceptionaquí).
Fundido con as
var myThing = someObject asThing;
Esto no arroja un InvalidCastExceptionpero devuelve un nullcuando falla el lanzamiento (y cuando someObjectes nulo). Así que ten cuidado con eso.
LINQ FirstOrDefault()ySingleOrDefault()
Las versiones simples First()y Single()lanzan excepciones cuando no hay nada. Las versiones "OrDefault" devuelven nulo en ese caso. Así que ten cuidado con eso.
para cada
foreacharroja cuando intenta iterar colección nula. Generalmente causado por un nullresultado inesperado de métodos que devuelven colecciones.
List<int> list =null;foreach(var v in list){}// exception
Ejemplo más realista: seleccione nodos del documento XML. Se lanzará si no se encuentran nodos, pero la depuración inicial muestra que todas las propiedades son válidas:
foreach(var node in myData.MyXml.DocumentNode.SelectNodes("//Data"))
Formas de evitar
Verifique explícitamente nulle ignore los valores nulos.
Si espera que la referencia a veces sea nula, puede verificarla nullantes de acceder a los miembros de la instancia:
Verifique explícitamente nully proporcione un valor predeterminado.
Los métodos de llamada que espera devolver pueden devolver una instancia null, por ejemplo, cuando no se puede encontrar el objeto que se busca. Puede elegir devolver un valor predeterminado cuando este sea el caso:
Verifique explícitamente las nullllamadas de método y arroje una excepción personalizada.
También puede lanzar una excepción personalizada, solo para atraparla en el código de llamada:
stringGetCategory(string bookTitle){var book = library.FindBook(bookTitle);// This may return nullif(book ==null)thrownewBookNotFoundException(bookTitle);// Your custom exceptionreturn book.Category;}
Use Debug.Assertsi un valor nunca debería ser null, para detectar el problema antes de que ocurra la excepción.
Cuando sabe durante el desarrollo que un método puede, pero nunca debería regresar null, puede usarlo Debug.Assert()para interrumpirlo tan pronto como sea posible:
stringGetTitle(int knownBookID){// You know this should never return null.var book = library.GetBook(knownBookID);// Exception will occur on the next line instead of at the end of this method.Debug.Assert(book !=null,"Library didn't return a book for known book ID.");// Some other codereturn book.Title;// Will never throw NullReferenceException in Debug mode.}
Aunque esta verificación no terminará en su versión de lanzamiento , lo que provocará que se lance NullReferenceExceptionnuevamente book == nullen tiempo de ejecución en modo de lanzamiento.
Use GetValueOrDefault()para los nullabletipos de valor para proporcionar un valor predeterminado cuando lo sean null.
DateTime? appointment =null;Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));// Will display the default value provided (DateTime.Now), because appointment is null.
appointment =newDateTime(2022,10,20);Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));// Will display the appointment date, not the default
Utilice el operador de fusión nulo: ??[C #] o If()[VB].
La abreviatura para proporcionar un valor predeterminado cuando nullse encuentra un:
IServiceCreateService(ILogger log,Int32? frobPowerLevel){var serviceImpl =newMyService(log ??NullLog.Instance);// Note that the above "GetValueOrDefault()" can also be rewritten to use// the coalesce operator:
serviceImpl.FrobPowerLevel= frobPowerLevel ??5;}
Utilice el operador de condición nula: ?.o ?[x]para matrices (disponible en C # 6 y VB.NET 14):
Esto a veces también se llama el operador de navegación segura o Elvis (después de su forma). Si la expresión en el lado izquierdo del operador es nula, entonces no se evaluará el lado derecho, y en su lugar se devolverá nulo. Eso significa casos como este:
var title = person.Title.ToUpper();
Si la persona no tiene un título, esto generará una excepción porque está intentando invocar ToUpperuna propiedad con un valor nulo.
A C# 5continuación, esto se puede proteger con:
var title = person.Title==null?null: person.Title.ToUpper();
Ahora la variable de título será nula en lugar de lanzar una excepción. C # 6 introduce una sintaxis más corta para esto:
var title = person.Title?.ToUpper();
Esto dará como resultado la variable de título null, y la llamada a ToUpperno se realiza si person.Titlees así null.
Por supuesto, aún tiene que verificar titlesi es nulo o utilizar el operador de condición nula junto con el operador de fusión nulo ( ??) para proporcionar un valor predeterminado:
// regular null checkint titleLength =0;if(title !=null)
titleLength = title.Length;// If title is null, this would throw NullReferenceException// combining the `?` and the `??` operatorint titleLength = title?.Length??0;
Del mismo modo, para las matrices puede usar ?[i]lo siguiente:
Esto hará lo siguiente: Si myIntArrayes nulo, la expresión devuelve nulo y puede verificarlo con seguridad. Si contiene una matriz, hará lo mismo que:
elem = myIntArray[i];y devuelve el i<sup>th</sup>elemento.
Usar contexto nulo (disponible en C # 8):
Introducido en el C# 8contexto nulo y los tipos de referencia anulables realizan un análisis estático de las variables y proporciona una advertencia del compilador si un valor puede ser potencialmente nulo o si se ha establecido en nulo. Los tipos de referencia anulables permiten que los tipos sean explícitamente nulos.
El contexto de anulación anulable y el contexto de advertencia anulable se pueden configurar para un proyecto utilizando el Nullableelemento en su csprojarchivo. Este elemento configura cómo el compilador interpreta la nulabilidad de los tipos y qué advertencias se generan. Las configuraciones válidas son:
enable: el contexto de anulación anulable está habilitado. El contexto de advertencia anulable está habilitado. Las variables de un tipo de referencia, cadena por ejemplo, no son anulables. Todas las advertencias de nulabilidad están habilitadas.
deshabilitar: el contexto de anulación anulable está deshabilitado. El contexto de advertencia anulable está deshabilitado. Las variables de un tipo de referencia son ajenas, al igual que las versiones anteriores de C #. Todas las advertencias de nulabilidad están deshabilitadas.
safeonly: el contexto de anotación anulable está habilitado. El contexto de advertencia anulable es seguro. Las variables de un tipo de referencia no son anulables. Todas las advertencias de nulabilidad de seguridad están habilitadas.
advertencias: el contexto de anotaciones anulables está deshabilitado. El contexto de advertencia anulable está habilitado. Las variables de un tipo de referencia son ajenas. Todas las advertencias de nulabilidad están habilitadas.
safeonlywarnings: el contexto de anulación anulable está deshabilitado. El contexto de advertencia anulable es seguro. Las variables de un tipo de referencia son ajenas. Todas las advertencias de nulabilidad de seguridad están habilitadas.
Se observa un tipo de referencia anulable utilizando la misma sintaxis que los tipos de valores anulables: a ?se agrega al tipo de la variable.
Técnicas especiales para depurar y corregir derefs nulos en iteradores
C#admite "bloques iteradores" (llamados "generadores" en algunos otros idiomas populares). Las excepciones de anulación de referencia pueden ser particularmente difíciles de depurar en bloques iteradores debido a la ejecución diferida:
publicIEnumerable<Frob>GetFrobs(FrobFactory f,int count){for(int i =0; i < count;++i)yieldreturn f.MakeFrob();}...FrobFactory factory = whatever;IEnumerable<Frobs> frobs =GetFrobs();...foreach(Frob frob in frobs){...}
Si whatevercomo resultado nullentonces MakeFroba tirar. Ahora, puede pensar que lo correcto es esto:
// DON'T DO THISpublicIEnumerable<Frob>GetFrobs(FrobFactory f,int count){if(f ==null)thrownewArgumentNullException("f","factory must not be null");for(int i =0; i < count;++i)yieldreturn f.MakeFrob();}
¿Por qué está mal esto? ¡Porque el bloque iterador no se ejecuta realmente hasta que foreach! La llamada a GetFrobssimplemente devuelve un objeto que cuando se itera ejecutará el bloque iterador.
Al escribir una verificación nula como esta, evita la desreferencia nula, pero mueve la excepción de argumento nulo al punto de la iteración , no al punto de la llamada , y eso es muy confuso para depurar .
La solución correcta es:
// DO THISpublicIEnumerable<Frob>GetFrobs(FrobFactory f,int count){// No yields in a public method that throws!if(f ==null)thrownewArgumentNullException("f","factory must not be null");returnGetFrobsForReal(f, count);}privateIEnumerable<Frob>GetFrobsForReal(FrobFactory f,int count){// Yields in a private methodDebug.Assert(f !=null);for(int i =0; i < count;++i)yieldreturn f.MakeFrob();}
Es decir, cree un método auxiliar privado que tenga la lógica de bloqueo del iterador y un método de superficie pública que haga la comprobación nula y devuelva el iterador. Ahora, cuando GetFrobsse llama, la verificación nula ocurre de inmediato y luego se GetFrobsForRealejecuta cuando la secuencia se repite.
Si examina la fuente de referencia para LINQObjetos, verá que esta técnica se utiliza en todo momento. Es un poco más torpe escribir, pero hace que la depuración de errores de nulidad sea mucho más fácil. Optimice su código para la conveniencia de la persona que llama, no la conveniencia del autor .
Una nota sobre desreferencias nulas en código inseguro
C#tiene un modo "inseguro" que, como su nombre lo indica, es extremadamente peligroso porque no se aplican los mecanismos de seguridad normales que proporcionan seguridad de memoria y de tipo. No debe escribir código inseguro a menos que tenga un conocimiento profundo y profundo de cómo funciona la memoria .
En modo inseguro, debe tener en cuenta dos hechos importantes:
desreferenciar un puntero nulo produce la misma excepción que desreferenciar una referencia nula
desreferenciar un puntero no nulo no válido puede producir esa excepción en algunas circunstancias
Para entender por qué es así, es útil entender cómo .NET produce excepciones de anulación de referencia en primer lugar. (Estos detalles se aplican a .NET que se ejecuta en Windows; otros sistemas operativos utilizan mecanismos similares).
La memoria está virtualizada en Windows; cada proceso obtiene un espacio de memoria virtual de muchas "páginas" de memoria que son rastreadas por el sistema operativo. Cada página de memoria tiene marcas establecidas que determinan cómo se puede usar: leer, escribir, ejecutar, etc. La página más baja está marcada como "producir un error si alguna vez se usa de alguna manera".
Tanto un puntero nulo como una referencia nula C#se representan internamente como el número cero, por lo que cualquier intento de desreferenciarlo en su almacenamiento de memoria correspondiente hace que el sistema operativo produzca un error. El tiempo de ejecución .NET luego detecta este error y lo convierte en la excepción de anulación de referencia nula.
Es por eso que desreferenciar tanto un puntero nulo como una referencia nula produce la misma excepción.
¿Qué pasa con el segundo punto? Anular la referencia a cualquier puntero no válido que se encuentre en la página más baja de la memoria virtual provoca el mismo error del sistema operativo y, por lo tanto, la misma excepción.
¿Por qué esto tiene sentido? Bueno, supongamos que tenemos una estructura que contiene dos entradas y un puntero no administrado igual a nulo. Si intentamos desreferenciar el segundo int en la estructura, CLRno intentaremos acceder al almacenamiento en la ubicación cero; accederá al almacenamiento en la ubicación cuatro. Pero lógicamente, esta es una anulación de referencia nula porque estamos llegando a esa dirección a través de la nula.
Si está trabajando con código inseguro y obtiene una excepción de anulación de referencia nula, solo tenga en cuenta que el puntero infractor no necesita ser nulo. Puede ser cualquier ubicación en la página más baja, y se producirá esta excepción.
Tal vez este es un comentario tonto, pero ¿no sería la primera y mejor manera de evitar este problema inicializar el objeto? Para mí, si ocurre este error, generalmente es porque olvidé inicializar algo como el elemento de matriz. Creo que es mucho menos común definir el objeto como nulo y luego hacer referencia a él. Tal vez dé la manera de resolver cada problema adyacente a la descripción. Sigue siendo una buena publicación.
JPK
30
¿Qué pasa si no hay ningún objeto, sino el valor de retorno de un método o propiedad?
John Saunders
66
El ejemplo del libro / autor es un poco raro ... ¿Cómo se compila eso? ¿Cómo funciona incluso el intellisense? ¿Qué es esto? No soy bueno con la computadora ...
55
@ Will: ¿ayuda mi última edición? De lo contrario, sea más explícito sobre lo que ve como un problema.
John Saunders
66
@ JohnSaunders Oh, no, lo siento, me refería a la versión inicializadora del objeto. new Book { Author = { Age = 45 } };¿Cómo funciona la inicialización interna incluso ... No puedo pensar en una situación en la que el init interno funcione alguna vez, sin embargo, compila e intellisense funciona ... A menos que sea para estructuras?
311
Excepción de referencia nula - Visual Basic
El NullReference Exceptionpara Visual Basic no es diferente del de C # . Después de todo, ambos informan la misma excepción definida en .NET Framework que ambos usan. Las causas exclusivas de Visual Basic son raras (quizás solo una).
Esta respuesta usará términos, sintaxis y contexto de Visual Basic. Los ejemplos utilizados provienen de una gran cantidad de preguntas anteriores de Stack Overflow. Esto es para maximizar la relevancia mediante el uso de los tipos de situaciones que a menudo se ven en las publicaciones. También se proporciona un poco más de explicación para aquellos que lo necesiten. Un ejemplo similar al suyo es muy probable que aparezca aquí.
Nota:
Esto está basado en el concepto: no hay código para pegar en su proyecto. Su objetivo es ayudarlo a comprender qué causa una NullReferenceException(NRE), cómo encontrarla, cómo solucionarla y cómo evitarla. Una NRE puede ser causada de muchas maneras, por lo que es poco probable que sea su único encuentro.
Los ejemplos (de las publicaciones de Stack Overflow) no siempre muestran la mejor manera de hacer algo en primer lugar.
Por lo general, se usa el remedio más simple.
Significado Básico
El mensaje "Objeto no establecido en una instancia de Object" significa que está intentando utilizar un objeto que no se ha inicializado. Esto se reduce a uno de estos:
Su código declaró una variable de objeto, pero no la inicializó (cree una instancia o ' instanciarla ')
Algo que su código asumió que inicializaría un objeto, no
Posiblemente, otro código invalida prematuramente un objeto que todavía está en uso
Encontrar la causa
Dado que el problema es una referencia a un objeto Nothing, la respuesta es examinarlos para averiguar cuál. Luego determine por qué no se inicializa. Mantenga el mouse sobre las diversas variables y Visual Studio (VS) mostrará sus valores, el culpable será Nothing.
También debe eliminar los bloques Try / Catch del código relevante, especialmente aquellos en los que no hay nada en el bloque Catch. Esto hará que su código se bloquee cuando intente usar un objeto que es Nothing. Esto es lo que desea porque identificará la ubicación exacta del problema y le permitirá identificar el objeto que lo causó.
A MsgBoxen la captura que muestra Error while...será de poca ayuda. Este método también lleva a preguntas de desbordamiento de pila muy malas , porque no puede describir la excepción real, el objeto involucrado o incluso la línea de código donde sucede.
También puede usar Locals Window( Depurar -> Windows -> Locales ) para examinar sus objetos.
Una vez que sepa cuál y dónde está el problema, generalmente es bastante fácil de solucionar y más rápido que publicar una nueva pregunta.
Dim reg As CashRegister
...
TextBox1.Text = reg.Amount ' NRE
El problema es que Dimno crea un objeto CashRegister ; solo declara una variable llamada regde ese tipo. Declarar una variable de objeto y crear una instancia son dos cosas diferentes.
Remedio
El Newoperador a menudo se puede usar para crear la instancia cuando la declaras:
Dim reg AsNew CashRegister ' [New] creates instance, invokes the constructor' Longer, more explicit form:Dim reg As CashRegister =New CashRegister
Cuando solo es apropiado crear la instancia más tarde:
Nota: No lo use Dimnuevamente en un procedimiento, incluido el constructor ( Sub New):
Private reg As CashRegister
'...PublicSubNew()'...Dim reg AsNew CashRegister
EndSub
Esto creará una variable localreg , que existe solo en ese contexto (sub). La regvariable con nivel de módulo Scopeque usará en cualquier otro lugar permanece Nothing.
La falta del Newoperador es la causa número 1 de loNullReference Exceptions visto en las preguntas de desbordamiento de pila revisadas.
Visual Basic intenta aclarar el proceso repetidamente utilizando New: El uso del Newoperador crea un nuevo objeto y llama Sub Newal constructor, donde su objeto puede realizar cualquier otra inicialización.
Para ser claros, Dim(o Private) solo declara una variable y su Type. El alcance de la variable, ya sea que exista para todo el módulo / clase o sea local para un procedimiento, se determina por el lugar donde se declara. Private | Friend | Publicdefine el nivel de acceso, no el alcance .
Esta matriz solo ha sido declarada, no creada. Hay varias formas de inicializar una matriz:
Private arr asString()=NewString(10){}' orPrivate arr()AsString=NewString(10){}' For a local array (in a procedure) and using 'Option Infer':Dim arr =NewString(10){}
Nota: a partir de VS 2010, al inicializar una matriz local utilizando un literal y Option Infer, los elementos As <Type>y Newson opcionales:
Dim myDbl AsDouble()={1.5,2,9.9,18,3.14}Dim myDbl =NewDouble(){1.5,2,9.9,18,3.14}Dim myDbl()={1.5,2,9.9,18,3.14}
El tipo de datos y el tamaño de la matriz se infieren de los datos que se asignan. Las declaraciones de nivel de clase / módulo aún requieren As <Type>con Option Strict:
Private myDoubles AsDouble()={1.5,2,9.9,18,3.14}
Ejemplo: matriz de objetos de clase
Dim arrFoo(5)As Foo
For i AsInteger=0To arrFoo.Count -1
arrFoo(i).Bar = i *10' ExceptionNext
La matriz se ha creado, pero los Fooobjetos que contiene no.
Remedio
For i AsInteger=0To arrFoo.Count -1
arrFoo(i)=New Foo()' Create Foo instance
arrFoo(i).Bar = i *10Next
Usar a List(Of T)hará que sea bastante difícil tener un elemento sin un objeto válido:
Dim FooList AsNew List(Of Foo)' List created, but it is emptyDim f As Foo ' Temporary variable for the loopFor i AsInteger=0To5
f =New Foo()' Foo instance created
f.Bar = i *10
FooList.Add(f)' Foo object added to listNext
Las colecciones .NET (de las cuales hay muchas variedades - Listas, Diccionario, etc.) también deben ser instanciadas o creadas.
Private myList As List(Of String)..
myList.Add("ziggy")' NullReference
Obtiene la misma excepción por el mismo motivo: myListsolo se declaró, pero no se creó ninguna instancia. El remedio es el mismo:
myList =New List(Of String)' Or create an instance when declared:Private myList AsNew List(Of String)
Un descuido común es una clase que usa una colección Type:
PublicClass Foo
Private barList As List(Of Bar)FriendFunction BarCount AsIntegerReturn barList.Count
EndFunctionFriendSub AddItem(newBar As Bar)If barList.Contains(newBar)=FalseThen
barList.Add(newBar)EndIfEndFunction
Cualquiera de los procedimientos dará como resultado una NRE, porque barListsolo se declara, no se instancia. Crear una instancia de Foono también creará una instancia de lo interno barList. Puede haber sido la intención de hacer esto en el constructor:
PublicSubNew' Constructor' Stuff to do when a new Foo is created...
barList =New List(Of Bar)EndSub
Como antes, esto es incorrecto:
PublicSubNew()' Creates another barList local to this procedureDim barList AsNew List(Of Bar)EndSub
Trabajar con bases de datos presenta muchas oportunidades para un NullReference porque no puede haber muchos objetos ( Command, Connection, Transaction, Dataset, DataTable, DataRows....) en el uso de una sola vez. Nota: No importa qué proveedor de datos esté utilizando (MySQL, SQL Server, OleDB, etc.), los conceptos son los mismos.
Ejemplo 1
Dim da As OleDbDataAdapter
Dim ds As DataSet
Dim MaxRows AsInteger
con.Open()Dim sql ="SELECT * FROM tblfoobar_List"
da =New OleDbDataAdapter(sql, con)
da.Fill(ds,"foobar")
con.Close()
MaxRows = ds.Tables("foobar").Rows.Count ' Error
Como antes, dsse declaró el objeto Dataset, pero nunca se creó una instancia. El DataAdapterllenará un existente DataSet, no creará uno. En este caso, dado que dses una variable local, el IDE le advierte que esto podría suceder:
Cuando se declara como una variable de nivel de módulo / clase, como parece ser el caso con, el compilador no puede saber si el objeto fue creado por un procedimiento ascendente. No ignore las advertencias.
Un error tipográfico es un problema aquí: Employeesvs Employee. No se DataTablecreó un nombre de "Empleado", por lo que los NullReferenceExceptionresultados intentaron acceder a él. Otro problema potencial es asumir que habrá lo Itemsque puede no ser así cuando el SQL incluye una cláusula WHERE.
Remedio
Como esto usa una tabla, el uso Tables(0)evitará errores ortográficos. El examen Rows.Counttambién puede ayudar:
If ds.Tables(0).Rows.Count >0Then
txtID.Text = ds.Tables(0).Rows(0).Item(1)
txtID.Name = ds.Tables(0).Rows(0).Item(2)EndIf
Filles una función que devuelve el número de Rowsafectados que también se puede probar:
If da.Fill(ds,"Employees")>0Then...
Ejemplo 3
Dim da AsNew OleDb.OleDbDataAdapter("SELECT TICKET.TICKET_NO,
TICKET.CUSTOMER_ID, ... FROM TICKET_RESERVATION AS TICKET INNER JOIN
FLIGHT_DETAILS AS FLIGHT ... WHERE [TICKET.TICKET_NO]= ...", con)Dim ds AsNew DataSet
da.Fill(ds)If ds.Tables("TICKET_RESERVATION").Rows.Count >0Then
La DataAdapterproporcionará TableNamescomo se muestra en el ejemplo anterior, pero no es así nombres de análisis sintáctico de la tabla o base de datos SQL. Como resultado, hace ds.Tables("TICKET_RESERVATION")referencia a una tabla inexistente.
El remedio es el mismo, consulte la tabla por índice:
El código solo está probando Itemsmientras ambos myFooy Bartambién puede ser Nothing. El remedio es probar la cadena o ruta completa de los objetos, uno a la vez:
AndAlsoes importante. Las pruebas posteriores no se realizarán una vez Falseque se encuentre la primera condición. Esto permite que el código 'se desplace' de forma segura en el (los) objeto (s) un 'nivel' a la vez, evaluando myFoo.Barsolo después de (y si) myFoose determina que es válido. Las cadenas o rutas de objetos pueden ser bastante largas al codificar objetos complejos:
Aquí, myWebBrowsero Documentpodría ser Nada o el formfld1elemento puede no existir.
Controles de UI
Dim cmd5 AsNew SqlCommand("select Cartons, Pieces, Foobar " _
&"FROM Invoice where invoice_no = '"& _
Me.ComboBox5.SelectedItem.ToString.Trim &"' And category = '"& _
Me.ListBox1.SelectedItem.ToString.Trim &"' And item_name = '"& _
Me.ComboBox2.SelectedValue.ToString.Trim &"' And expiry_date = '"& _
Me.expiry.Text &"'", con)
Entre otras cosas, este código no anticipa que el usuario no haya seleccionado algo en uno o más controles de IU. ListBox1.SelectedItembien puede ser Nothing, por ListBox1.SelectedItem.ToStringlo que resultará en una NRE.
Remedio
Valide los datos antes de usarlos (también use Option Stricty parámetros SQL):
Dim expiry As DateTime ' for text date validationIf(ComboBox5.SelectedItems.Count >0)AndAlso(ListBox1.SelectedItems.Count >0)AndAlso(ComboBox2.SelectedItems.Count >0)AndAlso(DateTime.TryParse(expiry.Text, expiry)Then'... do stuffElse
MessageBox.Show(...error message...)EndIf
PublicClass Form1
Private NameBoxes =New TextBox(5){Controls("TextBox1"), _
Controls("TextBox2"), Controls("TextBox3"), _
Controls("TextBox4"), Controls("TextBox5"), _
Controls("TextBox6")}' same thing in a different format:Private boxList AsNew List(Of TextBox) From {TextBox1, TextBox2, TextBox3 ...}' Immediate NRE:Private somevar AsString=Me.Controls("TextBox1").Text
Esta es una forma bastante común de obtener una NRE. En C #, dependiendo de cómo esté codificado, el IDE informará que Controlsno existe en el contexto actual o que "no puede hacer referencia a un miembro no estático". Entonces, hasta cierto punto, esta es una situación de solo VB. También es complejo porque puede provocar una cascada de fallas.
Las matrices y colecciones no se pueden inicializar de esta manera. Este código de inicialización se ejecutará antes de que el constructor cree el Formo el Controls. Como resultado:
Las listas y la colección simplemente estarán vacías
The Array contendrá cinco elementos de Nothing
La somevarasignación dará como resultado una NRE inmediata porque Nothing no tiene una .Textpropiedad
Hacer referencia a elementos de la matriz más adelante dará como resultado una NRE. Si hace esto Form_Load, debido a un error extraño, el IDE puede no informar la excepción cuando ocurra. La excepción aparecerá más tarde cuando su código intente usar la matriz. Esta "excepción silenciosa" se detalla en esta publicación . Para nuestros propósitos, la clave es que cuando ocurre algo catastrófico al crear un formulario ( Sub Newo Form Loadevento), las excepciones pueden no ser reportadas, el código sale del procedimiento y solo muestra el formulario.
Dado que ningún otro código en tu Sub Newo Form Loadevento se desarrollará después de la NRE, un gran número de otras cosas se pueden dejar sin inicializar.
Sub Form_Load(..._
'...Dim name AsString= NameBoxes(2).Text ' NRE' ...' More code (which will likely not be executed)' ...EndSub
Tenga en cuenta que esto se aplica a todas y cada una de las referencias de control y componentes que las hacen ilegales donde están:
Es curioso que VB no proporciona una advertencia, pero el remedio es declarar los contenedores en el nivel de la forma, pero inicializar en controlador de eventos de carga de formulario cuando los controles hacen existir. Esto se puede hacer Sub Newsiempre que su código esté después de la InitializeComponentllamada:
' Module level declarationPrivate NameBoxes as TextBox()Private studentName AsString' Form Load, Form Shown or Sub New:'' Using the OP's approach (illegal using OPTION STRICT)
NameBoxes =New TextBox(){Me.Controls("TextBox1"),Me.Controls("TestBox2"),...)
studentName = TextBox32.Text ' For simple control references
Es posible que el código de matriz aún no esté fuera de peligro. Los controles que están en un control de contenedor (como a GroupBoxo Panel) no se encontrarán en Me.Controls; estarán en la colección de Controles de ese Panel o GroupBox. Tampoco se devolverá un control cuando el nombre del control esté mal escrito ( "TeStBox2"). En tales casos, Nothingse almacenará nuevamente en esos elementos de la matriz y se producirá un NRE cuando intente hacer referencia a él.
Estos deberían ser fáciles de encontrar ahora que sabe lo que está buscando:
"Button2" reside en un Panel
Remedio
En lugar de referencias indirectas por nombre usando la Controlscolección del formulario , use la referencia de control:
' DeclarationPrivate NameBoxes As TextBox()' Initialization - simple and easy to read, hard to botch:
NameBoxes =New TextBox(){TextBox1, TextBox2,...)' Initialize a List
NamesList =New List(Of TextBox)({TextBox1, TextBox2, TextBox3...})' or
NamesList =New List(Of TextBox)
NamesList.AddRange({TextBox1, TextBox2, TextBox3...})
Función que no devuelve nada
Private bars AsNew List(Of Bars)' Declared and createdPublicFunction BarList()As List(Of Bars)
bars.Clear
If someCondition ThenFor n AsInteger=0to someValue
bars.Add(GetBar(n))Next n
ElseExitFunctionEndIfReturn bars
EndFunction
Este es un caso en el que el IDE le advertirá que " no todas las rutas devuelven un valor y NullReferenceExceptionpueden resultar ". Puede suprimir la advertencia, reemplazando Exit Functioncon Return Nothing, pero eso no resuelve el problema. Cualquier cosa que intente usar el retorno cuando someCondition = Falsedará como resultado una NRE:
bList = myFoo.BarList()ForEach b As Bar in bList ' EXCEPTION...
Remedio
Reemplazar Exit Functionen la función con Return bList. Devolver un vacíoList no es lo mismo que devolver Nothing. Si existe la posibilidad de que se pueda devolver un objeto Nothing, pruebe antes de usarlo:
Un Try / Catch mal implementado puede ocultar dónde está el problema y generar otros nuevos:
Dim dr As SqlDataReader
TryDim lnk As LinkButton = TryCast(sender, LinkButton)Dim gr As GridViewRow =DirectCast(lnk.NamingContainer, GridViewRow)Dim eid AsString= GridView1.DataKeys(gr.RowIndex).Value.ToString()
ViewState("username")= eid
sqlQry ="select FirstName, Surname, DepartmentName, ExtensionName, jobTitle,
Pager, mailaddress, from employees1 where username='"& eid &"'"If connection.State <> ConnectionState.Open Then
connection.Open()EndIf
command =New SqlCommand(sqlQry, connection)'More code fooing and barring
dr = command.ExecuteReader()If dr.Read()Then
lblFirstName.Text = Convert.ToString(dr("FirstName"))...EndIf
mpe.Show()CatchFinally
command.Dispose()
dr.Close()' <-- NRE
connection.Close()EndTry
Este es un caso de un objeto que no se crea como se esperaba, pero también demuestra la utilidad del contador de un vacío Catch.
Hay una coma adicional en el SQL (después de 'mailaddress') que da como resultado una excepción en .ExecuteReader. Después de Catchque no hace nada, Finallyintenta realizar la limpieza, pero como no puede Closeun DataReaderobjeto nulo , se NullReferenceExceptionobtienen resultados completamente nuevos .
Un Catchbloque vacío es el patio del diablo. Este OP estaba desconcertado por qué estaba obteniendo una NRE en el Finallybloque. En otras situaciones, un vacío Catchpuede dar lugar a que algo mucho más alejado se vuelva loco y hacer que pase tiempo mirando las cosas incorrectas en el lugar equivocado para el problema. (La "excepción silenciosa" descrita anteriormente proporciona el mismo valor de entretenimiento).
Remedio
No use bloques vacíos Try / Catch: deje que el código se bloquee para que pueda a) identificar la causa b) identificar la ubicación yc) aplicar un remedio adecuado. Los bloques Try / Catch no están destinados a ocultar excepciones de la persona calificada para solucionarlos: el desarrollador.
DBNull no es lo mismo que Nothing
ForEach row As DataGridViewRow In dgvPlanning.Rows
IfNot IsDBNull(row.Cells(0).Value)Then...
La IsDBNullfunción se usa para probar si un valor es igual a System.DBNull: Desde MSDN:
El valor System.DBNull indica que el Objeto representa datos faltantes o inexistentes. DBNull no es lo mismo que Nothing, lo que indica que una variable aún no se ha inicializado.
Remedio
If row.Cells(0) IsNot NothingThen...
Como antes, puede probar para Nada, luego para un valor específico:
Dim getFoo =(From f In dbContext.FooBars
Where f.something = something
Select f).FirstOrDefault
IfNot IsDBNull(getFoo)ThenIf IsDBNull(getFoo.user_id)Then
txtFirst.Text = getFoo.first_name
Else...
FirstOrDefaultdevuelve el primer elemento o el valor predeterminado, que es Nothingpara tipos de referencia y nunca DBNull:
If getFoo IsNot NothingThen...
Control S
Dim chk As CheckBox
chk =CType(Me.Controls(chkName), CheckBox)If chk.Checked ThenReturn chk
EndIf
Si no se puede encontrar un CheckBoxwith chkName(o existe en a GroupBox), entonces chkserá Nothing e intentar hacer referencia a cualquier propiedad dará como resultado una excepción.
Remedio
If(chk IsNot Nothing)AndAlso(chk.Checked)Then...
El DataGridView
El DGV tiene algunas peculiaridades que se ven periódicamente:
Si dgvBookses AutoGenerateColumns = Trueasí, creará las columnas, pero no las nombrará, por lo que el código anterior falla cuando hace referencia a ellas por su nombre.
Remedio
Nombre las columnas manualmente, o haga referencia por índice:
Cuando DataGridViewtiene AllowUserToAddRowscomo True(el valor predeterminado), todo Cellsen la fila en blanco / nueva en la parte inferior contendrá Nothing. La mayoría de los intentos de usar el contenido (por ejemplo ToString) dará como resultado una NRE.
Remedio
Use un For/Eachbucle y pruebe la IsNewRowpropiedad para determinar si es esa última fila. Esto funciona si AllowUserToAddRowses cierto o no:
ForEach r As DataGridViewRow in myDGV.Rows
If r.IsNewRow =FalseThen' ok to use this row
Si usa un For nbucle, modifique el recuento de filas o use Exit Forcuándo IsNewRowes verdadero.
My.Settings (StringCollection)
Bajo ciertas circunstancias, tratar de usar un elemento del My.Settingscual es un StringCollectionpuede resultar en una NullReference la primera vez que la use. La solución es la misma, pero no tan obvia. Considerar:
My.Settings.FooBars.Add("ziggy")' foobars is a string collection
Dado que VB administra la configuración por usted, es razonable esperar que inicialice la recopilación. Lo hará, pero solo si ha agregado previamente una entrada inicial a la colección (en el editor de Configuración). Como la colección se inicializa (aparentemente) cuando se agrega un elemento, permanece Nothingcuando no hay elementos en el editor de Configuración para agregar.
Remedio
Inicialice la colección de configuraciones en el Loadcontrolador de eventos del formulario , si es necesario:
If My.Settings.FooBars IsNothingThen
My.Settings.FooBars =New System.Collections.Specialized.StringCollection
EndIf
Por lo general, la Settingscolección solo deberá inicializarse la primera vez que se ejecute la aplicación. Una solución alternativa es agregar un valor inicial a su colección en Proyecto -> Configuración | FooBars , guarde el proyecto, luego elimine el valor falso.
Puntos clave
Probablemente olvidaste el Newoperador.
o
Algo que asumió que funcionaría perfectamente para devolver un objeto inicializado a su código, no lo hizo.
No ignore las advertencias del compilador (nunca) y use Option Strict On(siempre).
Otro escenario es cuando convierte un objeto nulo en un tipo de valor . Por ejemplo, el siguiente código:
object o =null;DateTime d =(DateTime)o;
Lanzará un NullReferenceExceptionsobre el elenco. Parece bastante obvio en el ejemplo anterior, pero esto puede suceder en escenarios intrincados más "de enlace tardío" en los que el objeto nulo ha sido devuelto por algún código que no es de su propiedad, y el reparto es generado, por ejemplo, por algún sistema automático.
Un ejemplo de esto es este fragmento de enlace ASP.NET simple con el control Calendar:
Aquí, SelectedDatede hecho , es una propiedad, de DateTimetipo, del Calendartipo Control web, y el enlace podría devolver algo nulo perfectamente. El Generador ASP.NET implícito creará un fragmento de código que será equivalente al código de transmisión anterior. Y esto generará un problema NullReferenceExceptionque es bastante difícil de detectar, ya que se encuentra en el código generado por ASP.NET que se compila bien ...
Eso arrojará el error porque aunque he declarado la variable " connection", no apunta a nada. Cuando intento llamar al miembro " Open", no hay ninguna referencia para resolverlo y arrojará el error.
Para evitar este error:
Siempre inicialice sus objetos antes de intentar hacer algo con ellos.
Si no está seguro de si el objeto es nulo, verifíquelo con object == null.
La herramienta Resharper de JetBrains identificará cada lugar en su código que tenga la posibilidad de un error de referencia nulo, lo que le permite realizar una verificación nula. Este error es la fuente número uno de errores, en mi humilde opinión.
La herramienta Resharper de JetBrains identificará cada lugar en su código que tenga la posibilidad de un error de referencia nulo. Esto es incorrecto. Tengo una solución sin esa detección, pero el código ocasionalmente resulta en la excepción. Sospecho que en ocasiones es indetectable, al menos por ellos, cuando se trata de subprocesos múltiples, pero no puedo comentar más porque todavía no identifiqué la ubicación de mi error.
j riv
Pero cómo resolverlo cuando NullReferenceException viene en usign HttpContext.Current.Responce.Clear (). No se resuelve con ninguna de las soluciones anteriores. porque al crear su objeto objeto de HttpContext aparece un error "La resolución de sobrecarga falló porque ningún 'Nuevo' accesible acepta este Número de argumentos.
Sunny Sandeep
158
Significa que su código utilizó una variable de referencia de objeto que se estableció en nulo (es decir, no hizo referencia a una instancia de objeto real).
Para evitar el error, los objetos que podrían ser nulos deben ser probados para nulo antes de ser utilizados.
if(myvar !=null){// Go ahead and use myvar
myvar.property=...}else{// Whoops! myvar is null and cannot be used without first// assigning it to an instance reference// Attempting to use myvar here will result in NullReferenceException}
Tenga en cuenta que, independientemente del escenario, la causa es siempre la misma en .NET:
Está intentando utilizar una variable de referencia cuyo valor es Nothing/ null. Cuando el valor es Nothing/ nullpara la variable de referencia, eso significa que en realidad no contiene una referencia a una instancia de ningún objeto que exista en el montón.
Nunca asignó algo a la variable, nunca creó una instancia del valor asignado a la variable, o configuró la variable igual Nothing/ nullmanualmente, o llamó a una función que establezca la variable en Nothing/ nullpara usted.
Un ejemplo de esta excepción lanzada es: cuando intenta verificar algo, eso es nulo.
Por ejemplo:
string testString =null;//Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)if(testString.Length==0)// Throws a nullreferenceexception{//Do something}
El tiempo de ejecución de .NET generará una NullReferenceException cuando intente realizar una acción en algo que no se haya instanciado, es decir, el código anterior.
En comparación con una excepción ArgumentNullException que generalmente se lanza como una medida defensiva si un método espera que lo que se le pasa no sea nulo.
C # 8.0 introduce tipos de referencia anulables y tipos de referencia no anulables . Tipos de referencia por lo que sólo admiten nulos deben ser evaluados para evitar una NullReferenceException .
Si no ha inicializado un tipo de referencia y desea establecer o leer una de sus propiedades, arrojará una NullReferenceException .
Ejemplo:
Person p =null;
p.Name="Harry";// NullReferenceException occurs here.
Simplemente puede evitar esto comprobando si la variable no es nula:
Person p =null;if(p!=null){
p.Name="Harry";// Not going to run to this point}
Para comprender completamente por qué se produce una NullReferenceException, es importante conocer la diferencia entre los tipos de valor y [tipos de referencia] [3].
Por lo tanto, si se trata de tipos de valores , NullReferenceExceptions no puede ocurrir. ¡Aunque debe mantenerse alerta al tratar con tipos de referencia !
Solo los tipos de referencia, como sugiere el nombre, pueden contener referencias o apuntar literalmente a nada (o 'nulo'). Mientras que los tipos de valor siempre contienen un valor.
Tipos de referencia (estos deben ser verificados):
-1: dado que la pregunta es "¿Qué es una NullReferenceException", los tipos de valor no son relevantes.
John Saunders,
21
@ John Saunders: No estoy de acuerdo. Como desarrollador de software, es realmente importante poder distinguir entre el valor y los tipos de referencia. de lo contrario, las personas terminarán verificando si los enteros son nulos.
Fabian Bigler
55
Es cierto, simplemente no en el contexto de esta pregunta.
John Saunders
44
Gracias por la pista. Lo mejoré un poco y agregué un ejemplo en la parte superior. Todavía creo que mencionar los tipos de referencia y valor es útil.
Fabian Bigler
55
Creo que no ha agregado nada que no estaba en las otras respuestas, ya que la pregunta supone un tipo de referencia.
John Saunders
78
Otro caso en el que NullReferenceExceptionspuede suceder es el uso (incorrecto) del asoperador :
Aquí, Booky Carson tipos incompatibles; a Carno se puede convertir / lanzar a a Book. Cuando este lanzamiento falla, asregresa null. Usar mybookdespués de esto causa a NullReferenceException.
En general, debe usar un yeso o as, de la siguiente manera:
Si espera que la conversión de tipos siempre tenga éxito (es decir, sabe cuál debe ser el objeto antes de tiempo), entonces debe usar un molde:
ComicBook cb =(ComicBook)specificBook;
Si no está seguro del tipo, pero desea intentar usarlo como un tipo específico, use as:
Esto puede suceder mucho al desempaquetar una variable. Encuentro que sucede a menudo en los controladores de eventos después de cambiar el tipo del elemento de la interfaz de usuario, pero olvido actualizar el código subyacente.
Brendan
65
Está utilizando el objeto que contiene la referencia de valor nulo. Entonces está dando una excepción nula. En el ejemplo, el valor de la cadena es nulo y, al verificar su longitud, se produjo la excepción.
Ejemplo:
stringvalue=null;if(value.Length==0)// <-- Causes exception{Console.WriteLine(value);// <-- Never reached}
El error de excepción es:
Excepción no controlada:
System.NullReferenceException: referencia de objeto no establecida en una instancia de un objeto. en Program.Main ()
¡Qué profundo! Nunca consideré la constante 'nula' como un valor de referencia. Así es como C # abstrae un "puntero nulo" ¿eh? B / c, como recuerdo en C ++, un NPE puede ser causado al desreferenciar un puntero no inicializado (es decir, tipo de referencia en c #) cuyo valor predeterminado es una dirección que no está asignada a ese proceso (en muchos casos esto sería 0, especialmente en versiones posteriores de C ++ que hicieron la autoinicialización, que pertenece al sistema operativo, con él y mueren (o simplemente detecta el sigkill con el que el sistema operativo ataca su proceso)).
samis
64
Si bien lo que causa un NullReferenceExceptions y los enfoques para evitar / solucionar dicha excepción se han abordado en otras respuestas, lo que muchos programadores aún no han aprendido es cómo depurar de forma independiente dichas excepciones durante el desarrollo.
Ahora, cuando se lanza la NullReferenceException (o no se controla), el depurador se detendrá (¿recuerda la regla establecida anteriormente?) En la línea en la que ocurrió la excepción. A veces el error será fácil de detectar.
Por ejemplo, en la siguiente línea, el único código que puede causar la excepción es si se myStringevalúa como nulo. Esto se puede verificar mirando la Ventana de Observación o ejecutando expresiones en la Ventana Inmediata .
var x = myString.Trim();
En casos más avanzados, como los siguientes, deberá usar una de las técnicas anteriores (Watch o Windows Inmediato) para inspeccionar las expresiones para determinar si str1era nulo o si str2era nulo.
var x = str1.Trim()+ str2.Trim();
Una vez que se ha localizado la excepción, generalmente es trivial razonar hacia atrás para descubrir dónde se introdujo [incorrectamente] el valor nulo:
Tómese el tiempo necesario para comprender la causa de la excepción. Inspeccione las expresiones nulas. Inspeccione las expresiones anteriores que podrían haber resultado en tales expresiones nulas. Agregue puntos de interrupción y avance por el programa según corresponda. Usa el depurador.
1 Si Break on Throws es demasiado agresivo y el depurador se detiene en un NPE en la biblioteca .NET o de terceros, se puede usar Break on User-Unledled para limitar las excepciones detectadas. Además, VS2012 presenta Just My Code, que recomiendo habilitar también.
Si está depurando con Just My Code habilitado, el comportamiento es ligeramente diferente. Con Just My Code habilitado, el depurador ignora las excepciones de Common Language Runtime (CLR) de primera oportunidad que se arrojan fuera de My Code y no pasan por My Code
object o =null;DateTime d =(DateTime)o;// NullReferenceException
donde una conversión de unboxing (cast) deobject (o de una de las clases System.ValueTypeo System.Enum, o de un tipo de interfaz) a un tipo de valor (que no seaNullable<> ) en sí mismo proporciona el NullReferenceException.
En la otra dirección, una conversión de boxeo de una Nullable<>que tieneHasValue igual falsea un tipo de referencia, puede dar una nullreferencia que luego puede conducir a a NullReferenceException. El ejemplo clásico es:
DateTime? d =null;var s = d.ToString();// OK, no exception (no boxing), returns ""var t = d.GetType();// Bang! d is boxed, NullReferenceException
A veces el boxeo ocurre de otra manera. Por ejemplo con este método de extensión no genérico:
Agregar un caso cuando el nombre de la clase para la entidad utilizada en el marco de la entidad es el mismo que el nombre de la clase para un archivo de código subyacente de formulario web.
Supongamos que tiene un formulario web Contact.aspx cuya clase de código subyacente es Contact y tiene un nombre de entidad Contact.
Luego, el siguiente código arrojará una NullReferenceException cuando llame a context.SaveChanges ()
Contact contact =newContact{Name="Abhinav"};var context =newDataContext();
context.Contacts.Add(contact);
context.SaveChanges();// NullReferenceException at this line
El error ocurre cuando la entidad y la clase codebehind están en el mismo espacio de nombres. Para solucionar esto, cambie el nombre de la clase de entidad o la clase de código subyacente para Contact.aspx.
Razón
Todavía no estoy seguro del motivo. Pero cada vez que cualquiera de la clase de entidad extenderá System.Web.UI.Page, se produce este error.
Otro caso general en el que uno podría recibir esta excepción implica burlarse de las clases durante las pruebas unitarias. Independientemente del marco de simulación que se utilice, debe asegurarse de que todos los niveles apropiados de la jerarquía de clases se burlen correctamente. En particular, todas las propiedades deHttpContext deben burlar que hace referencia el código bajo prueba.
Tengo una perspectiva diferente para responder esto. Este tipo de respuestas "¿qué más puedo hacer para evitarlo? "
Cuando se trabaja en diferentes capas , por ejemplo en una aplicación MVC, un controlador necesita servicios para llamar a las operaciones comerciales. En tales escenarios, el Contenedor de inyección de dependencias se puede utilizar para inicializar los servicios para evitar la NullReferenceException . Eso significa que no necesita preocuparse por verificar nulos y simplemente llamar a los servicios desde el controlador como si siempre estuvieran disponibles (e inicializados) como un singleton o un prototipo.
publicclassMyController{privateServiceA serviceA;privateServiceB serviceB;publicMyController(ServiceA serviceA,ServiceB serviceB){this.serviceA = serviceA;this.serviceB = serviceB;}publicvoidMyMethod(){// We don't need to check null because the dependency injection container // injects it, provided you took care of bootstrapping it.var someObject = serviceA.DoThis();}}
-1: esto solo maneja un escenario único: el de las dependencias no inicializadas. Este es un escenario minoritario para NullReferenceException. La mayoría de los casos son simples malentendidos sobre cómo funcionan los objetos. Los siguientes más frecuentes son otras situaciones en las que el desarrollador asumió que el objeto se inicializaría automáticamente.
John Saunders
La inyección de dependencia generalmente no se usa para evitar NullReferenceException. No creo que hayas encontrado un escenario general aquí. En cualquier caso, si edita su respuesta para que sea más al estilo de stackoverflow.com/a/15232518/76337 , eliminaré el voto negativo.
John Saunders
38
En cuanto a "qué debo hacer al respecto" , puede haber muchas respuestas.
Una forma más "formal" de prevenir tales condiciones de error durante el desarrollo es aplicar el diseño por contrato en su código. Esto significa que necesita establecer invariantes de clase , y / o incluso precondiciones y postcondiciones de función / método en su sistema, durante el desarrollo.
En resumen, los invariantes de clase aseguran que habrá algunas restricciones en su clase que no serán violadas en el uso normal (y, por lo tanto, la clase no entrará en un estado inconsistente). Las condiciones previas significan que los datos proporcionados como entrada para una función / método deben seguir algunas restricciones establecidas y nunca violarlas, y las condiciones posteriores significan que una salida de función / método debe seguir las restricciones establecidas nuevamente sin violarlas nunca. Las condiciones del contrato nunca deben violarse durante la ejecución de un programa libre de errores, por lo tanto, el diseño por contrato se verifica en la práctica en modo de depuración, mientras se desactiva en las versiones , para maximizar el rendimiento del sistema desarrollado.
De esta manera, puede evitar NullReferenceExceptioncasos que son el resultado de la violación de las restricciones establecidas. Por ejemplo, si usa una propiedad de objeto Xen una clase y luego intenta invocar uno de sus métodos y Xtiene un valor nulo, esto conducirá a NullReferenceException:
public X {get;set;}publicvoidInvokeX(){
X.DoSomething();// if X value is null, you will get a NullReferenceException}
Pero si establece "la propiedad X nunca debe tener un valor nulo" como condición previa del método, puede evitar el escenario descrito anteriormente:
//Using code contracts:[ContractInvariantMethod]protectedvoidObjectInvariant(){Contract.Invariant( X !=null);//...}
Por esta causa, el proyecto de contratos de código existe para aplicaciones .NET.
Alternativamente, el diseño por contrato se puede aplicar utilizando aserciones .
Pensé agregar esto ya que nadie lo mencionó, y en la medida en que exista un enfoque, mi intención era enriquecer el tema.
Nick Louloudakis
2
Gracias por enriquecer el tema. He dado mi opinión sobre su incorporación. Ahora otros pueden hacer lo mismo.
John Saunders
2
Pensé que esto era una adición valiosa al tema dado que este es un hilo muy visto. He oído hablar de contratos de código antes y este fue un buen recordatorio para considerar usarlos.
VoteCoffee
36
Se NullReferenceExceptiongenera A cuando intentamos acceder a las Propiedades de un objeto nulo o cuando un valor de cadena se vacía y estamos intentando acceder a métodos de cadena.
Por ejemplo:
Cuando se accede a un método de cadena de una cadena vacía:
Esto es incorrecto. String.Empty.ToLower()no lanzará una excepción de referencia nula. Representa una cadena real, aunque vacía (es decir ""). Como esto tiene un objeto al que invocar ToLower(), no tendría sentido lanzar una excepción de referencia nula allí.
Kjartan
31
TL; DR: intente usar en Html.Partiallugar deRenderpage
Obtuve Object reference not set to an instance of an objectcuando traté de representar una Vista dentro de una Vista enviándole un Modelo, como este:
@{MyEntity M =newMyEntity();}@RenderPage("_MyOtherView.cshtml", M);// error in _MyOtherView, the Model was Null
La depuración mostró que el modelo era Nulo dentro de MyOtherView. Hasta que lo cambié a:
@{MyEntity M =newMyEntity();}@Html.Partial("_MyOtherView.cshtml", M);
Y funcionó.
Además, la razón por la que no tuve Html.Partialque comenzar fue porque Visual Studio a veces arroja líneas onduladas con aspecto de error Html.Partialsi está dentro de un foreachbucle de construcción diferente , aunque en realidad no es un error:
@inheritsSystem.Web.Mvc.WebViewPage@{ViewBag.Title="Entity Index";List<MyEntity>MyEntities=newList<MyEntity>();MyEntities.Add(newMyEntity());MyEntities.Add(newMyEntity());MyEntities.Add(newMyEntity());}<div>@{foreach(var M inMyEntities){// Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?@Html.Partial("MyOtherView.cshtml");}}</div>
Pero pude ejecutar la aplicación sin problemas con este "error". Pude deshacerme del error cambiando la estructura del foreachbucle para que se vea así:
@foreach(var M inMyEntities){...}
Aunque tengo la sensación de que fue porque Visual Studio estaba leyendo mal los símbolos y los corchetes.
Además, muestre qué línea arrojó la excepción y por qué.
John Saunders
El error ocurrió en MyOtherView.cshtml, que no incluí aquí, porque el Modelo no se estaba enviando correctamente (sí Null), así que sabía que el error estaba en cómo estaba enviando el Modelo.
Travis Heeter
22
¿Qué puedes hacer al respecto?
Aquí hay muchas buenas respuestas que explican qué es una referencia nula y cómo depurarla. Pero hay muy poco sobre cómo prevenir el problema o al menos facilitar su detección.
Verificar argumentos
Por ejemplo, los métodos pueden verificar los diferentes argumentos para ver si son nulos y arrojar un ArgumentNullException, una excepción obviamente creada para este propósito exacto.
El constructor para el ArgumentNullExceptionpar toma el nombre del parámetro y un mensaje como argumentos para que pueda decirle al desarrollador exactamente cuál es el problema.
publicvoidDoSomething(MyObject obj){if(obj ==null){thrownewArgumentNullException("obj","Need a reference to obj.");}}
Usar herramientas
También hay varias bibliotecas que pueden ayudar. "Resharper", por ejemplo, puede proporcionarle advertencias mientras escribe código, especialmente si usa su atributo: NotNullAttribute
Hay "Contratos de código de Microsoft" donde usa una sintaxis como la Contract.Requires(obj != null)que le da tiempo de ejecución y compilación de verificación: Introducción de contratos de código .
También hay "PostSharp" que le permitirá usar atributos como este:
publicvoidDoSometing([NotNull] obj)
Al hacer eso y hacer que PostSharp forme parte de su proceso de compilación obj, se verificará que no es nulo en tiempo de ejecución. Ver: verificación nula PostSharp
Solución de código simple
O siempre puede codificar su propio enfoque utilizando un código antiguo simple. Por ejemplo, aquí hay una estructura que puede usar para capturar referencias nulas. Se basa en el mismo concepto que Nullable<T>:
[System.Diagnostics.DebuggerNonUserCode]publicstructNotNull<T>where T:class{private T _value;public T Value{get{if(_value ==null){thrownewException("null value not allowed");}return _value;}set{if(value==null){thrownewException("null value not allowed.");}
_value =value;}}publicstaticimplicitoperator T(NotNull<T> notNullValue){return notNullValue.Value;}publicstaticimplicitoperatorNotNull<T>(T value){returnnewNotNull<T>{Value=value};}}
Usaría una forma muy similar a la misma que usaría Nullable<T>, excepto con el objetivo de lograr exactamente lo contrario: no permitir null. Aquí hay unos ejemplos:
NotNull<Person> person =null;// throws exceptionNotNull<Person> person =newPerson();// OKNotNull<Person> person =GetPerson();// throws exception if GetPerson() returns null
NotNull<T>está implícitamente emitido hacia y desde Tpara que pueda usarlo en cualquier lugar donde lo necesite. Por ejemplo, puede pasar un Personobjeto a un método que tome un NotNull<Person>:
Person person =newPerson{Name="John"};WriteName(person);publicstaticvoidWriteName(NotNull<Person> person){Console.WriteLine(person.Value.Name);}
Como puede ver arriba, como con nulable, accedería al valor subyacente a través de la Valuepropiedad. Alternativamente, puede usar una conversión explícita o implícita, puede ver un ejemplo con el valor de retorno a continuación:
Person person =GetPerson();publicstaticNotNull<Person>GetPerson(){returnnewPerson{Name="John"};}
O incluso puede usarlo cuando el método simplemente regrese T(en este caso Person) haciendo un lanzamiento. Por ejemplo, al siguiente código le gustaría el código anterior:
Person person =(NotNull<Person>)GetPerson();publicstaticPersonGetPerson(){returnnewPerson{Name="John"};}
Combinar con extensión
Combine NotNull<T>con un método de extensión y puede cubrir incluso más situaciones. Aquí hay un ejemplo de cómo puede verse el método de extensión:
[System.Diagnostics.DebuggerNonUserCode]publicstaticclassNotNullExtension{publicstatic T NotNull<T>(this T @this)where T:class{if(@this==null){thrownewException("null value not allowed");}return@this;}}
Y aquí hay un ejemplo de cómo podría usarse:
var person =GetPerson().NotNull();
GitHub
Para su referencia, hice que el código anterior esté disponible en GitHub, puede encontrarlo en:
C # 6.0 introdujo el "operador nulo-condicional" que ayuda un poco con esto. Con esta función, puede hacer referencia a objetos anidados y, si alguno de ellos es nullla expresión completa, regresa null.
Esto reduce la cantidad de comprobaciones nulas que tiene que hacer en algunos casos. La sintaxis es poner un signo de interrogación antes de cada punto. Tome el siguiente código, por ejemplo:
var address = country?.State?.County?.City;
Imagine que countryes un objeto de tipo Countryque tiene una propiedad llamada Statey así sucesivamente. Si country, State, County, o Cityes nullentonces address will benula . Therefore you only have to check whetherdirección isnull`.
Es una gran característica, pero le brinda menos información. No hace obvio cuál de los 4 es nulo.
¿Incorporado como Nullable?
C # tiene una buena abreviatura para Nullable<T>, puede hacer que algo sea anulable poniendo un signo de interrogación después del tipo de esta manera int?.
Sería bueno si C # tenido algo así como la NotNull<T>estructura anterior y tenía una taquigrafía similares, tal vez el signo de exclamación para que usted podría escribir algo como (!): public void WriteName(Person! person).
@JohnSaunders me atrevo a preguntar ¿por qué? (¿En serio, por qué?)
Luis Pérez
2
NullReferenceException está destinado a ser lanzado por el CLR. Significa que se ha producido una referencia a un valor nulo. No significa que ocurra una referencia a un valor nulo, excepto que usted primero verificó hábilmente.
John Saunders
Veo su punto sobre cómo eso sería confuso. Lo actualicé a una excepción regular para este ejemplo y una excepción personalizada en GitHub.
Luis Perez
Gran respuesta para una pregunta tan básica. No es tan malo cuando es tu código el que falla. Es horrible cuando proviene de una biblioteca de terceros comercial en la que confía, y el servicio de atención al cliente sigue insistiendo en que tiene que ser su código el que está causando el problema. Y no estás del todo seguro de que no lo sea y todo el proyecto está paralizado. De hecho, creo que esto podría ser un epitafio apropiado para mi lápida: "La referencia de objeto no está establecida en una instancia de un objeto".
Darrel Lee
10
Curiosamente, ninguna de las respuestas en esta página menciona los dos casos extremos, espero que a nadie le importe si los agrego:
Caso límite # 1: acceso concurrente a un diccionario
Los diccionarios genéricos en .NET no son seguros para subprocesos y a veces pueden arrojar un NullReferenceo incluso (más frecuente) unKeyNotFoundException cuando intenta acceder a una clave desde dos subprocesos simultáneos. La excepción es bastante engañosa en este caso.
Caso de borde # 2: código inseguro
Si el código NullReferenceExceptionarroja una unsafe, puede mirar las variables de puntero y verificar siIntPtr.Zero o algo así. Lo que es lo mismo ("excepción de puntero nulo"), pero en el código inseguro, las variables a menudo se convierten en tipos / matrices de valores, etc., y te golpeas la cabeza contra la pared, preguntándote cómo un tipo de valor puede arrojar esto excepción.
(Por cierto, otra razón para no usar código inseguro a menos que lo necesite)
Su ejemplo de diccionario no es un caso límite. Si el objeto no es seguro para subprocesos, su uso desde múltiples subprocesos produce resultados aleatorios. ¿Su ejemplo de código inseguro difiere de nullqué manera?
John Saunders
10
Puede arreglar NullReferenceException de manera limpia utilizando operadores condicional nulo en c # 6 y escribir menos código para manejar las comprobaciones nulas.
Se utiliza para probar nulo antes de realizar una operación de acceso de miembro (?.) O índice (? [).
Ejemplo
var name = p?.Spouse?.FirstName;
es equivalente a:
if(p !=null){if(p.Spouse!=null){
name = p.Spouse.FirstName;}}
El resultado es que el nombre será nulo cuando p sea nulo o cuando p.Spouse sea nulo.
De lo contrario, al nombre de la variable se le asignará el valor de p.Spouse.FirstName.
La línea de error "Referencia de objeto no establecida en una instancia de un objeto" indica que no ha asignado un objeto de instancia a una referencia de objeto y que aún está accediendo a propiedades / métodos de ese objeto.
por ejemplo: supongamos que tiene una clase llamada myClass y contiene una propiedad prop1.
publicClass myClass
{publicint prop1 {get;set;}}
Ahora está accediendo a este prop1 en alguna otra clase, como a continuación:
publicclassDemo{publicvoid testMethod(){
myClass ref=null;ref.prop1 =1;//This line throws error}}
la línea anterior arroja un error porque la referencia de la clase myClass se declara pero no se instancia o una instancia del objeto no se asigna a la referencia de esa clase.
Para solucionar esto, debe crear una instancia (asignar objeto a la referencia de esa clase).
NullReferenceException o la referencia de objeto no establecida en una instancia de un objeto se produce cuando un objeto de la clase que está intentando utilizar no se instancia. Por ejemplo:
Como se ve en el código anterior, la declaración
Student s - solo declara la variable de tipo Student, tenga en cuenta que la clase Student no se instancia en este punto. Por lo tanto, cuando se ejecuta la instrucción s.GetFullName () , arrojará la NullReferenceException.
Está intentando acceder a un objeto que no está creado o que actualmente no está en la memoria.
Entonces, cómo abordar esto:
Depura y deja que el depurador se rompa ... Te llevará directamente a la variable que está rota ... Ahora tu tarea es simplemente solucionar esto ... Usando la nueva palabra clave en el lugar apropiado.
Si se produce en algunos comandos de la base de datos porque el objeto no está presente, entonces todo lo que necesita hacer es hacer una verificación nula y manejarlo:
if(i ==null){// Handle this}
El más difícil ... si el GC ya recolectó el objeto ... Esto generalmente ocurre si está tratando de encontrar un objeto usando cadenas ... Es decir, si lo encuentra por el nombre del objeto, puede suceder que el GC ya pueda lo limpió ... Esto es difícil de encontrar y se convertirá en un gran problema ... Una mejor manera de abordar esto es realizar comprobaciones nulas siempre que sea necesario durante el proceso de desarrollo. Esto te ahorrara mucho tiempo.
Al encontrar por nombre me refiero a que algún marco le permite FIndObjects usando cadenas y el código podría verse así: FindObject ("ObjectName");
Si tiene una referencia a un objeto, entonces el GC nunca lo limpia
John Saunders
2
si usa cosas como FindObject ("Nombre del objeto") no hay manera de que GC sepa de antemano que va a hacer referencia a ese objeto ... esto es lo que estaba tratando de explicar ... esto ocurre en tiempo de ejecución
Akash Gutha
2
Hay algunos marcos que proporcionan esta funcionalidad en C #, como Unity. La pregunta no tiene nada relacionado con BCl. Busque en Internet antes de criticar que hay un montón de funciones como estas y para obtener información amable, incluso la uso a diario. Ahora por favor dime cómo la respuesta no tiene sentido.
Los ejemplos que vi en su enlace asignan los resultados de GameObject.Find a un campo miembro. Esa es una referencia y el GC no lo recopilará hasta que se recopile el objeto que lo contiene.
John Saunders
1
Literalmente, la forma más fácil de arreglar una NullReferenceExeption tiene dos formas. Si tiene un GameObject, por ejemplo, con un script adjunto y una variable llamada rb (cuerpo rígido), esta variable comenzará nula cuando inicie el juego.
Es por eso que obtiene una NullReferenceExeption porque la computadora no tiene datos almacenados en esa variable.
Usaré una variable RigidBody como ejemplo.
Podemos agregar datos realmente fácilmente de varias maneras:
Agregue un RigidBody a su objeto con AddComponent> Physics> Rigidbody
Luego ingrese a su script y escriba rb = GetComponent<Rigidbody>();
Esta línea de código funciona mejor bajo sus funciones Start()o Awake().
Puede agregar un componente mediante programación y asignar la variable al mismo tiempo con una línea de código: rb = AddComponent<RigidBody>();
Notas adicionales: Si desea la unidad para agregar un componente a su objeto y puede haber olvidado agregar uno, puede escribir [RequireComponent(typeof(RigidBody))]arriba de su declaración de clase (el espacio debajo de todos sus usos).
¡Disfruta y diviértete haciendo juegos!
Si consideramos escenarios comunes donde se puede lanzar esta excepción, accedemos a las propiedades dentro del objeto en la parte superior.
Ex:
string postalcode=Customer.Address.PostalCode;//if customer or address is null , this will through exeption
aquí, si la dirección es nula, obtendrá NullReferenceException.
Por lo tanto, como práctica, siempre debemos usar la verificación nula, antes de acceder a las propiedades de dichos objetos (especialmente en genéricos)
string postalcode=Customer?.Address?.PostalCode;//if customer or address is null , this will return null, without through a exception
Esto es básicamente una excepción de referencia nula . Como Microsoft Unidos-
Se produce una excepción NullReferenceException cuando intenta acceder a un miembro de un tipo cuyo valor es nulo.
Qué significa eso?
Eso significa que si algún miembro que no tiene ningún valor y estamos haciendo que ese miembro realice cierta tarea, el sistema indudablemente arrojará un mensaje y dirá:
"Oye, espera, ese miembro no tiene valores, por lo que no puede realizar la tarea que le estás entregando".
La excepción en sí dice que se está refiriendo algo pero cuyo valor no se está estableciendo. Esto denota que solo ocurre mientras se usan tipos de referencia, ya que los tipos de Valor no son anulables.
NullReferenceException no ocurrirá si estamos utilizando miembros de tipo Value.
El código anterior muestra una cadena simple que se asigna con un valor nulo .
Ahora, cuando intento imprimir la longitud de la cadena str , recibo un mensaje de excepción no controlada del tipo 'System.NullReferenceException' porque el miembro str apunta a nulo y no puede haber ninguna longitud nula.
' NullReferenceException ' también ocurre cuando olvidamos instanciar un tipo de referencia.
Supongamos que tengo una clase y un método miembro. No he instanciado mi clase, sino que solo he nombrado mi clase. Ahora, si trato de usar el método, el compilador arrojará un error o emitirá una advertencia (dependiendo del compilador).
classProgram{staticvoidMain(string[] args){MyClass1 obj;
obj.foo();//Use of unassigned local variable 'obj'}}publicclassMyClass1{internalvoid foo(){Console.WriteLine("hello from foo");}}
El compilador para el código anterior genera un error de que la variable obj no está asignada, lo que significa que nuestra variable tiene valores nulos o nada. El compilador para el código anterior genera un error de que la variable obj no está asignada, lo que significa que nuestra variable tiene valores nulos o nada.
¿Por qué ocurre?
NullReferenceException surge debido a nuestra culpa por no verificar el valor del objeto. A menudo dejamos los valores del objeto sin marcar en el desarrollo del código.
También surge cuando olvidamos instanciar nuestros objetos. El uso de métodos, propiedades, colecciones, etc. que pueden devolver o establecer valores nulos también puede ser la causa de esta excepción.
¿Cómo se puede evitar?
Hay varias formas y métodos para evitar esta reconocida excepción:
Comprobación explícita: debemos cumplir con la tradición de comprobar los objetos, propiedades, métodos, matrices y colecciones si son nulos. Esto se puede implementar simplemente usando declaraciones condicionales como if-else if-else, etc.
Manejo de excepciones: una de las formas importantes de gestionar esta excepción. Usando simples bloques try-catch-finally podemos controlar esta excepción y también mantener un registro de la misma. Esto puede ser muy útil cuando su aplicación está en etapa de producción.
Operadores nulos: el operador de fusión nula y los operadores condicionales nulos también se pueden usar a la vez que se configuran valores para objetos, variables, propiedades y campos.
Depurador: para los desarrolladores, tenemos el gran arma de la depuración con nosotros. Si nos enfrentamos a NullReferenceException durante el desarrollo, podemos usar el depurador para llegar al origen de la excepción.
Método incorporado: los métodos del sistema como GetValueOrDefault (), IsNullOrWhiteSpace () e IsNullorEmpty () comprueban nulos y asignan el valor predeterminado si hay un valor nulo.
Ya hay muchas buenas respuestas aquí. También puede consultar una descripción más detallada con ejemplos en mi blog .
Básicamente copió la mitad de esa publicación de blog y no agregó nada nuevo que las respuestas existentes no aborden.
CodeCaster
@codecaster ¿Se dice copiar cuando reescribes un resumen de tu propio blog? Sé que no hay nada nuevo en mi respuesta y nada nuevo que las respuestas anteriores no tengan, pero deseo contribuir de una manera más sofisticada y dejar que otros entiendan la forma en que yo entendí. Se alegrará incluso si ayuda a una sola persona. De buena fe.
Wasim
-4
Si uno recibe este mensaje durante el guardado o la compilación de la compilación, simplemente cierre todos los archivos y luego abra cualquier archivo para compilar y guardar.
Para mí, la razón era que había cambiado el nombre del archivo y el archivo antiguo todavía estaba abierto.
Respuestas:
¿Cual es la causa?
Línea de fondo
Está intentando usar algo que es
null
(oNothing
en VB.NET). Esto significa que lo configurónull
o nunca lo configuró para nada.Como cualquier otra cosa,
null
se pasa. Si esnull
en el método "A", podría ser que el método "B" pasó unanull
de método "A".null
puede tener diferentes significados:NullReferenceException
.null
intencionalmente para indicar que no hay un valor significativo disponible. Tenga en cuenta que C # tiene el concepto de tipos de datos anulables para variables (como las tablas de la base de datos pueden tener campos anulables); puede asignarlosnull
para indicar que no hay ningún valor almacenado en él, por ejemplo,int? a = null;
donde el signo de interrogación indica que está permitido almacenar nulo en variablea
. Puede verificar eso conif (a.HasValue) {...}
o conif (a==null) {...}
. Las variables anulables, comoa
este ejemplo, permiten acceder al valor a través de formaa.Value
explícita, o de manera normal a través dea
.Tenga en cuenta que acceder a él a través de
a.Value
arroja un enInvalidOperationException
lugar de unNullReferenceException
ifa
esnull
- debe hacer la verificación de antemano, es decir, si tiene otra variable anulableint b;
, debe hacer asignaciones comoif (a.HasValue) { b = a.Value; }
o más cortasif (a != null) { b = a; }
.El resto de este artículo entra en más detalles y muestra errores que muchos programadores a menudo cometen y que pueden conducir a una
NullReferenceException
.Más específicamente
La
runtime
lanzar unaNullReferenceException
siempre significa lo mismo: usted está tratando de utilizar una referencia, y la referencia no se ha inicializado (o fue una vez inicializado, sino que está ya no inicializado).Esto significa que la referencia es
null
, y no puede acceder a los miembros (como los métodos) a través de unanull
referencia. El caso más simple:Esto arrojará un
NullReferenceException
en la segunda línea porque no puede llamar al método de instanciaToUpper()
en unastring
referencia que apuntanull
.Depuración
¿Cómo encuentras la fuente de un
NullReferenceException
? Además de mirar la excepción en sí, que se lanzará exactamente en el lugar donde ocurre, se aplican las reglas generales de depuración en Visual Studio: coloque puntos de interrupción estratégicos e inspeccione sus variables , ya sea colocando el mouse sobre sus nombres, abriendo un ( Rápido) Mire la ventana o use los diversos paneles de depuración como Locales y Autos.Si desea averiguar dónde se establece o no la referencia, haga clic con el botón derecho en su nombre y seleccione "Buscar todas las referencias". Luego puede colocar un punto de interrupción en cada ubicación encontrada y ejecutar su programa con el depurador adjunto. Cada vez que el depurador se interrumpe en dicho punto de interrupción, debe determinar si espera que la referencia no sea nula, inspeccionar la variable y verificar que apunta a una instancia cuando lo espera.
Siguiendo el flujo del programa de esta manera, puede encontrar la ubicación donde la instancia no debe ser nula y por qué no está configurada correctamente.
Ejemplos
Algunos escenarios comunes donde se puede lanzar la excepción:
Genérico
Si ref1 o ref2 o ref3 es nulo, obtendrá un
NullReferenceException
. Si desea resolver el problema, descubra cuál es nulo reescribiendo la expresión a su equivalente más simple:Específicamente, en
HttpContext.Current.User.Identity.Name
,HttpContext.Current
podría ser nulo, o laUser
propiedad podría ser nula, o laIdentity
propiedad podría ser nula.Indirecto
Si desea evitar la referencia nula secundaria (Persona), puede inicializarla en el constructor del objeto primario (Libro).
Inicializadores de objetos anidados
Lo mismo se aplica a los inicializadores de objetos anidados:
Esto se traduce en
Mientras
new
se usa la palabra clave, solo crea una nueva instancia deBook
, pero no una nueva instancia dePerson
, por lo queAuthor
la propiedad sigue siendonull
.Inicializadores de colecciones anidadas
La colección anidada se
Initializers
comporta igual:Esto se traduce en
El
new Person
único crea una instancia dePerson
, pero laBooks
colección sigue siendonull
. LaInitializer
sintaxis de la colección no crea una colecciónp1.Books
, solo se traduce en lasp1.Books.Add(...)
declaraciones.Formación
Elementos de matriz
Matrices Dentadas
Colección / Lista / Diccionario
Rango Variable (indirecto / diferido)
Eventos
public class Form1 {cliente de cliente privado;
}
Esto se puede resolver siguiendo la convención para prefijar campos con un guión bajo:
Ciclo de vida de la página ASP.NET:
Valores de sesión ASP.NET
Modelos de vista vacía ASP.NET MVC
Si la excepción ocurre cuando se hace referencia a una propiedad de
@Model
en unASP.NET MVC View
, debe comprender queModel
se establece en su método de acción, cuandoreturn
ve. Cuando devuelve un modelo vacío (o propiedad de modelo) desde su controlador, la excepción ocurre cuando las vistas acceden a él:Orden de creación de control de WPF y eventos
WPF
Los controles se crean durante la llamada aInitializeComponent
en el orden en que aparecen en el árbol visual. A seNullReferenceException
generará en el caso de controles creados con controladores de eventos, etc., que se activan durante losInitializeComponent
cuales se hace referencia a los controles creados tarde.Por ejemplo :
Aquí
comboBox1
se crea anteslabel1
. SicomboBox1_SelectionChanged
intenta hacer referencia a `label1, aún no se habrá creado.Cambiar el orden de las declaraciones en el
XAML
(es decir, enumerarlabel1
antescomboBox1
, ignorar los problemas de la filosofía del diseño, al menos resolveríaNullReferenceException
aquí).Fundido con
as
Esto no arroja un
InvalidCastException
pero devuelve unnull
cuando falla el lanzamiento (y cuandosomeObject
es nulo). Así que ten cuidado con eso.LINQ
FirstOrDefault()
ySingleOrDefault()
Las versiones simples
First()
ySingle()
lanzan excepciones cuando no hay nada. Las versiones "OrDefault" devuelven nulo en ese caso. Así que ten cuidado con eso.para cada
foreach
arroja cuando intenta iterar colección nula. Generalmente causado por unnull
resultado inesperado de métodos que devuelven colecciones.Ejemplo más realista: seleccione nodos del documento XML. Se lanzará si no se encuentran nodos, pero la depuración inicial muestra que todas las propiedades son válidas:
Formas de evitar
Verifique explícitamente
null
e ignore los valores nulos.Si espera que la referencia a veces sea nula, puede verificarla
null
antes de acceder a los miembros de la instancia:Verifique explícitamente
null
y proporcione un valor predeterminado.Los métodos de llamada que espera devolver pueden devolver una instancia
null
, por ejemplo, cuando no se puede encontrar el objeto que se busca. Puede elegir devolver un valor predeterminado cuando este sea el caso:Verifique explícitamente las
null
llamadas de método y arroje una excepción personalizada.También puede lanzar una excepción personalizada, solo para atraparla en el código de llamada:
Use
Debug.Assert
si un valor nunca debería sernull
, para detectar el problema antes de que ocurra la excepción.Cuando sabe durante el desarrollo que un método puede, pero nunca debería regresar
null
, puede usarloDebug.Assert()
para interrumpirlo tan pronto como sea posible:Aunque esta verificación no terminará en su versión de lanzamiento , lo que provocará que se lance
NullReferenceException
nuevamentebook == null
en tiempo de ejecución en modo de lanzamiento.Use
GetValueOrDefault()
para losnullable
tipos de valor para proporcionar un valor predeterminado cuando lo seannull
.Utilice el operador de fusión nulo:
??
[C #] oIf()
[VB].La abreviatura para proporcionar un valor predeterminado cuando
null
se encuentra un:Utilice el operador de condición nula:
?.
o?[x]
para matrices (disponible en C # 6 y VB.NET 14):Esto a veces también se llama el operador de navegación segura o Elvis (después de su forma). Si la expresión en el lado izquierdo del operador es nula, entonces no se evaluará el lado derecho, y en su lugar se devolverá nulo. Eso significa casos como este:
Si la persona no tiene un título, esto generará una excepción porque está intentando invocar
ToUpper
una propiedad con un valor nulo.A
C# 5
continuación, esto se puede proteger con:Ahora la variable de título será nula en lugar de lanzar una excepción. C # 6 introduce una sintaxis más corta para esto:
Esto dará como resultado la variable de título
null
, y la llamada aToUpper
no se realiza siperson.Title
es asínull
.Por supuesto, aún tiene que verificar
title
si es nulo o utilizar el operador de condición nula junto con el operador de fusión nulo (??
) para proporcionar un valor predeterminado:Del mismo modo, para las matrices puede usar
?[i]
lo siguiente:Esto hará lo siguiente: Si
myIntArray
es nulo, la expresión devuelve nulo y puede verificarlo con seguridad. Si contiene una matriz, hará lo mismo que:elem = myIntArray[i];
y devuelve eli<sup>th</sup>
elemento.Usar contexto nulo (disponible en C # 8):
Introducido en el
C# 8
contexto nulo y los tipos de referencia anulables realizan un análisis estático de las variables y proporciona una advertencia del compilador si un valor puede ser potencialmente nulo o si se ha establecido en nulo. Los tipos de referencia anulables permiten que los tipos sean explícitamente nulos.El contexto de anulación anulable y el contexto de advertencia anulable se pueden configurar para un proyecto utilizando el
Nullable
elemento en sucsproj
archivo. Este elemento configura cómo el compilador interpreta la nulabilidad de los tipos y qué advertencias se generan. Las configuraciones válidas son:Se observa un tipo de referencia anulable utilizando la misma sintaxis que los tipos de valores anulables: a
?
se agrega al tipo de la variable.Técnicas especiales para depurar y corregir derefs nulos en iteradores
C#
admite "bloques iteradores" (llamados "generadores" en algunos otros idiomas populares). Las excepciones de anulación de referencia pueden ser particularmente difíciles de depurar en bloques iteradores debido a la ejecución diferida:Si
whatever
como resultadonull
entoncesMakeFrob
a tirar. Ahora, puede pensar que lo correcto es esto:¿Por qué está mal esto? ¡Porque el bloque iterador no se ejecuta realmente hasta que
foreach
! La llamada aGetFrobs
simplemente devuelve un objeto que cuando se itera ejecutará el bloque iterador.Al escribir una verificación nula como esta, evita la desreferencia nula, pero mueve la excepción de argumento nulo al punto de la iteración , no al punto de la llamada , y eso es muy confuso para depurar .
La solución correcta es:
Es decir, cree un método auxiliar privado que tenga la lógica de bloqueo del iterador y un método de superficie pública que haga la comprobación nula y devuelva el iterador. Ahora, cuando
GetFrobs
se llama, la verificación nula ocurre de inmediato y luego seGetFrobsForReal
ejecuta cuando la secuencia se repite.Si examina la fuente de referencia para
LINQ
Objetos, verá que esta técnica se utiliza en todo momento. Es un poco más torpe escribir, pero hace que la depuración de errores de nulidad sea mucho más fácil. Optimice su código para la conveniencia de la persona que llama, no la conveniencia del autor .Una nota sobre desreferencias nulas en código inseguro
C#
tiene un modo "inseguro" que, como su nombre lo indica, es extremadamente peligroso porque no se aplican los mecanismos de seguridad normales que proporcionan seguridad de memoria y de tipo. No debe escribir código inseguro a menos que tenga un conocimiento profundo y profundo de cómo funciona la memoria .En modo inseguro, debe tener en cuenta dos hechos importantes:
Para entender por qué es así, es útil entender cómo .NET produce excepciones de anulación de referencia en primer lugar. (Estos detalles se aplican a .NET que se ejecuta en Windows; otros sistemas operativos utilizan mecanismos similares).
La memoria está virtualizada en
Windows
; cada proceso obtiene un espacio de memoria virtual de muchas "páginas" de memoria que son rastreadas por el sistema operativo. Cada página de memoria tiene marcas establecidas que determinan cómo se puede usar: leer, escribir, ejecutar, etc. La página más baja está marcada como "producir un error si alguna vez se usa de alguna manera".Tanto un puntero nulo como una referencia nula
C#
se representan internamente como el número cero, por lo que cualquier intento de desreferenciarlo en su almacenamiento de memoria correspondiente hace que el sistema operativo produzca un error. El tiempo de ejecución .NET luego detecta este error y lo convierte en la excepción de anulación de referencia nula.Es por eso que desreferenciar tanto un puntero nulo como una referencia nula produce la misma excepción.
¿Qué pasa con el segundo punto? Anular la referencia a cualquier puntero no válido que se encuentre en la página más baja de la memoria virtual provoca el mismo error del sistema operativo y, por lo tanto, la misma excepción.
¿Por qué esto tiene sentido? Bueno, supongamos que tenemos una estructura que contiene dos entradas y un puntero no administrado igual a nulo. Si intentamos desreferenciar el segundo int en la estructura,
CLR
no intentaremos acceder al almacenamiento en la ubicación cero; accederá al almacenamiento en la ubicación cuatro. Pero lógicamente, esta es una anulación de referencia nula porque estamos llegando a esa dirección a través de la nula.Si está trabajando con código inseguro y obtiene una excepción de anulación de referencia nula, solo tenga en cuenta que el puntero infractor no necesita ser nulo. Puede ser cualquier ubicación en la página más baja, y se producirá esta excepción.
fuente
new Book { Author = { Age = 45 } };
¿Cómo funciona la inicialización interna incluso ... No puedo pensar en una situación en la que el init interno funcione alguna vez, sin embargo, compila e intellisense funciona ... A menos que sea para estructuras?Excepción de referencia nula - Visual Basic
El
NullReference Exception
para Visual Basic no es diferente del de C # . Después de todo, ambos informan la misma excepción definida en .NET Framework que ambos usan. Las causas exclusivas de Visual Basic son raras (quizás solo una).Esta respuesta usará términos, sintaxis y contexto de Visual Basic. Los ejemplos utilizados provienen de una gran cantidad de preguntas anteriores de Stack Overflow. Esto es para maximizar la relevancia mediante el uso de los tipos de situaciones que a menudo se ven en las publicaciones. También se proporciona un poco más de explicación para aquellos que lo necesiten. Un ejemplo similar al suyo es muy probable que aparezca aquí.
Nota:
NullReferenceException
(NRE), cómo encontrarla, cómo solucionarla y cómo evitarla. Una NRE puede ser causada de muchas maneras, por lo que es poco probable que sea su único encuentro.Significado Básico
El mensaje "Objeto no establecido en una instancia de Object" significa que está intentando utilizar un objeto que no se ha inicializado. Esto se reduce a uno de estos:
Encontrar la causa
Dado que el problema es una referencia a un objeto
Nothing
, la respuesta es examinarlos para averiguar cuál. Luego determine por qué no se inicializa. Mantenga el mouse sobre las diversas variables y Visual Studio (VS) mostrará sus valores, el culpable seráNothing
.También debe eliminar los bloques Try / Catch del código relevante, especialmente aquellos en los que no hay nada en el bloque Catch. Esto hará que su código se bloquee cuando intente usar un objeto que es
Nothing
. Esto es lo que desea porque identificará la ubicación exacta del problema y le permitirá identificar el objeto que lo causó.A
MsgBox
en la captura que muestraError while...
será de poca ayuda. Este método también lleva a preguntas de desbordamiento de pila muy malas , porque no puede describir la excepción real, el objeto involucrado o incluso la línea de código donde sucede.También puede usar
Locals Window
( Depurar -> Windows -> Locales ) para examinar sus objetos.Una vez que sepa cuál y dónde está el problema, generalmente es bastante fácil de solucionar y más rápido que publicar una nueva pregunta.
Ver también:
Ejemplos y remedios
Objetos de clase / Crear una instancia
El problema es que
Dim
no crea un objeto CashRegister ; solo declara una variable llamadareg
de ese tipo. Declarar una variable de objeto y crear una instancia son dos cosas diferentes.Remedio
El
New
operador a menudo se puede usar para crear la instancia cuando la declaras:Cuando solo es apropiado crear la instancia más tarde:
Nota: No lo use
Dim
nuevamente en un procedimiento, incluido el constructor (Sub New
):Esto creará una variable local
reg
, que existe solo en ese contexto (sub). Lareg
variable con nivel de móduloScope
que usará en cualquier otro lugar permaneceNothing
.Para ser claros,
Dim
(oPrivate
) solo declara una variable y suType
. El alcance de la variable, ya sea que exista para todo el módulo / clase o sea local para un procedimiento, se determina por el lugar donde se declara.Private | Friend | Public
define el nivel de acceso, no el alcance .Para más información, ver:
Matrices
Las matrices también deben ser instanciadas:
Esta matriz solo ha sido declarada, no creada. Hay varias formas de inicializar una matriz:
Nota: a partir de VS 2010, al inicializar una matriz local utilizando un literal y
Option Infer
, los elementosAs <Type>
yNew
son opcionales:El tipo de datos y el tamaño de la matriz se infieren de los datos que se asignan. Las declaraciones de nivel de clase / módulo aún requieren
As <Type>
conOption Strict
:Ejemplo: matriz de objetos de clase
La matriz se ha creado, pero los
Foo
objetos que contiene no.Remedio
Usar a
List(Of T)
hará que sea bastante difícil tener un elemento sin un objeto válido:Para más información, ver:
Listas y Colecciones
Las colecciones .NET (de las cuales hay muchas variedades - Listas, Diccionario, etc.) también deben ser instanciadas o creadas.
Obtiene la misma excepción por el mismo motivo:
myList
solo se declaró, pero no se creó ninguna instancia. El remedio es el mismo:Un descuido común es una clase que usa una colección
Type
:Cualquiera de los procedimientos dará como resultado una NRE, porque
barList
solo se declara, no se instancia. Crear una instancia deFoo
no también creará una instancia de lo internobarList
. Puede haber sido la intención de hacer esto en el constructor:Como antes, esto es incorrecto:
Para más información, ver
List(Of T)
Clase .Objetos de proveedor de datos
Trabajar con bases de datos presenta muchas oportunidades para un NullReference porque no puede haber muchos objetos (
Command
,Connection
,Transaction
,Dataset
,DataTable
,DataRows
....) en el uso de una sola vez. Nota: No importa qué proveedor de datos esté utilizando (MySQL, SQL Server, OleDB, etc.), los conceptos son los mismos.Ejemplo 1
Como antes,
ds
se declaró el objeto Dataset, pero nunca se creó una instancia. ElDataAdapter
llenará un existenteDataSet
, no creará uno. En este caso, dado queds
es una variable local, el IDE le advierte que esto podría suceder:Cuando se declara como una variable de nivel de módulo / clase, como parece ser el caso
con
, el compilador no puede saber si el objeto fue creado por un procedimiento ascendente. No ignore las advertencias.Remedio
Ejemplo 2
Un error tipográfico es un problema aquí:
Employees
vsEmployee
. No seDataTable
creó un nombre de "Empleado", por lo que losNullReferenceException
resultados intentaron acceder a él. Otro problema potencial es asumir que habrá loItems
que puede no ser así cuando el SQL incluye una cláusula WHERE.Remedio
Como esto usa una tabla, el uso
Tables(0)
evitará errores ortográficos. El examenRows.Count
también puede ayudar:Fill
es una función que devuelve el número deRows
afectados que también se puede probar:Ejemplo 3
La
DataAdapter
proporcionaráTableNames
como se muestra en el ejemplo anterior, pero no es así nombres de análisis sintáctico de la tabla o base de datos SQL. Como resultado, haceds.Tables("TICKET_RESERVATION")
referencia a una tabla inexistente.El remedio es el mismo, consulte la tabla por índice:
Ver también la clase DataTable .
Rutas de objeto / anidadas
El código solo está probando
Items
mientras ambosmyFoo
yBar
también puede ser Nothing. El remedio es probar la cadena o ruta completa de los objetos, uno a la vez:AndAlso
es importante. Las pruebas posteriores no se realizarán una vezFalse
que se encuentre la primera condición. Esto permite que el código 'se desplace' de forma segura en el (los) objeto (s) un 'nivel' a la vez, evaluandomyFoo.Bar
solo después de (y si)myFoo
se determina que es válido. Las cadenas o rutas de objetos pueden ser bastante largas al codificar objetos complejos:No es posible hacer referencia a nada 'aguas abajo' de un
null
objeto. Esto también se aplica a los controles:Aquí,
myWebBrowser
oDocument
podría ser Nada o elformfld1
elemento puede no existir.Controles de UI
Entre otras cosas, este código no anticipa que el usuario no haya seleccionado algo en uno o más controles de IU.
ListBox1.SelectedItem
bien puede serNothing
, porListBox1.SelectedItem.ToString
lo que resultará en una NRE.Remedio
Valide los datos antes de usarlos (también use
Option Strict
y parámetros SQL):Alternativamente, puedes usar
(ComboBox5.SelectedItem IsNot Nothing) AndAlso...
Formas de Visual Basic
Esta es una forma bastante común de obtener una NRE. En C #, dependiendo de cómo esté codificado, el IDE informará que
Controls
no existe en el contexto actual o que "no puede hacer referencia a un miembro no estático". Entonces, hasta cierto punto, esta es una situación de solo VB. También es complejo porque puede provocar una cascada de fallas.Las matrices y colecciones no se pueden inicializar de esta manera. Este código de inicialización se ejecutará antes de que el constructor cree el
Form
o elControls
. Como resultado:somevar
asignación dará como resultado una NRE inmediata porque Nothing no tiene una.Text
propiedadHacer referencia a elementos de la matriz más adelante dará como resultado una NRE. Si hace esto
Form_Load
, debido a un error extraño, el IDE puede no informar la excepción cuando ocurra. La excepción aparecerá más tarde cuando su código intente usar la matriz. Esta "excepción silenciosa" se detalla en esta publicación . Para nuestros propósitos, la clave es que cuando ocurre algo catastrófico al crear un formulario (Sub New
oForm Load
evento), las excepciones pueden no ser reportadas, el código sale del procedimiento y solo muestra el formulario.Dado que ningún otro código en tu
Sub New
oForm Load
evento se desarrollará después de la NRE, un gran número de otras cosas se pueden dejar sin inicializar.Tenga en cuenta que esto se aplica a todas y cada una de las referencias de control y componentes que las hacen ilegales donde están:
Remedio parcial
Es curioso que VB no proporciona una advertencia, pero el remedio es declarar los contenedores en el nivel de la forma, pero inicializar en controlador de eventos de carga de formulario cuando los controles hacen existir. Esto se puede hacer
Sub New
siempre que su código esté después de laInitializeComponent
llamada:Es posible que el código de matriz aún no esté fuera de peligro. Los controles que están en un control de contenedor (como a
GroupBox
oPanel
) no se encontrarán enMe.Controls
; estarán en la colección de Controles de ese Panel o GroupBox. Tampoco se devolverá un control cuando el nombre del control esté mal escrito ("TeStBox2"
). En tales casos,Nothing
se almacenará nuevamente en esos elementos de la matriz y se producirá un NRE cuando intente hacer referencia a él.Estos deberían ser fáciles de encontrar ahora que sabe lo que está buscando:
"Button2" reside en un
Panel
Remedio
En lugar de referencias indirectas por nombre usando la
Controls
colección del formulario , use la referencia de control:Función que no devuelve nada
Este es un caso en el que el IDE le advertirá que " no todas las rutas devuelven un valor y
NullReferenceException
pueden resultar ". Puede suprimir la advertencia, reemplazandoExit Function
conReturn Nothing
, pero eso no resuelve el problema. Cualquier cosa que intente usar el retorno cuandosomeCondition = False
dará como resultado una NRE:Remedio
Reemplazar
Exit Function
en la función conReturn bList
. Devolver un vacíoList
no es lo mismo que devolverNothing
. Si existe la posibilidad de que se pueda devolver un objetoNothing
, pruebe antes de usarlo:Prueba / captura mal implementada
Un Try / Catch mal implementado puede ocultar dónde está el problema y generar otros nuevos:
Este es un caso de un objeto que no se crea como se esperaba, pero también demuestra la utilidad del contador de un vacío
Catch
.Hay una coma adicional en el SQL (después de 'mailaddress') que da como resultado una excepción en
.ExecuteReader
. Después deCatch
que no hace nada,Finally
intenta realizar la limpieza, pero como no puedeClose
unDataReader
objeto nulo , seNullReferenceException
obtienen resultados completamente nuevos .Un
Catch
bloque vacío es el patio del diablo. Este OP estaba desconcertado por qué estaba obteniendo una NRE en elFinally
bloque. En otras situaciones, un vacíoCatch
puede dar lugar a que algo mucho más alejado se vuelva loco y hacer que pase tiempo mirando las cosas incorrectas en el lugar equivocado para el problema. (La "excepción silenciosa" descrita anteriormente proporciona el mismo valor de entretenimiento).Remedio
No use bloques vacíos Try / Catch: deje que el código se bloquee para que pueda a) identificar la causa b) identificar la ubicación yc) aplicar un remedio adecuado. Los bloques Try / Catch no están destinados a ocultar excepciones de la persona calificada para solucionarlos: el desarrollador.
DBNull no es lo mismo que Nothing
La
IsDBNull
función se usa para probar si un valor es igual aSystem.DBNull
: Desde MSDN:Remedio
Como antes, puede probar para Nada, luego para un valor específico:
Ejemplo 2
FirstOrDefault
devuelve el primer elemento o el valor predeterminado, que esNothing
para tipos de referencia y nuncaDBNull
:Control S
Si no se puede encontrar un
CheckBox
withchkName
(o existe en aGroupBox
), entonceschk
será Nothing e intentar hacer referencia a cualquier propiedad dará como resultado una excepción.Remedio
El DataGridView
El DGV tiene algunas peculiaridades que se ven periódicamente:
Si
dgvBooks
esAutoGenerateColumns = True
así, creará las columnas, pero no las nombrará, por lo que el código anterior falla cuando hace referencia a ellas por su nombre.Remedio
Nombre las columnas manualmente, o haga referencia por índice:
Ejemplo 2 - Cuidado con el NewRow
Cuando
DataGridView
tieneAllowUserToAddRows
comoTrue
(el valor predeterminado), todoCells
en la fila en blanco / nueva en la parte inferior contendráNothing
. La mayoría de los intentos de usar el contenido (por ejemploToString
) dará como resultado una NRE.Remedio
Use un
For/Each
bucle y pruebe laIsNewRow
propiedad para determinar si es esa última fila. Esto funciona siAllowUserToAddRows
es cierto o no:Si usa un
For n
bucle, modifique el recuento de filas o useExit For
cuándoIsNewRow
es verdadero.My.Settings (StringCollection)
Bajo ciertas circunstancias, tratar de usar un elemento del
My.Settings
cual es unStringCollection
puede resultar en una NullReference la primera vez que la use. La solución es la misma, pero no tan obvia. Considerar:Dado que VB administra la configuración por usted, es razonable esperar que inicialice la recopilación. Lo hará, pero solo si ha agregado previamente una entrada inicial a la colección (en el editor de Configuración). Como la colección se inicializa (aparentemente) cuando se agrega un elemento, permanece
Nothing
cuando no hay elementos en el editor de Configuración para agregar.Remedio
Inicialice la colección de configuraciones en el
Load
controlador de eventos del formulario , si es necesario:Por lo general, la
Settings
colección solo deberá inicializarse la primera vez que se ejecute la aplicación. Una solución alternativa es agregar un valor inicial a su colección en Proyecto -> Configuración | FooBars , guarde el proyecto, luego elimine el valor falso.Puntos clave
Probablemente olvidaste el
New
operador.o
Algo que asumió que funcionaría perfectamente para devolver un objeto inicializado a su código, no lo hizo.
No ignore las advertencias del compilador (nunca) y use
Option Strict On
(siempre).Excepción de referencia nula de MSDN
fuente
Otro escenario es cuando convierte un objeto nulo en un tipo de valor . Por ejemplo, el siguiente código:
Lanzará un
NullReferenceException
sobre el elenco. Parece bastante obvio en el ejemplo anterior, pero esto puede suceder en escenarios intrincados más "de enlace tardío" en los que el objeto nulo ha sido devuelto por algún código que no es de su propiedad, y el reparto es generado, por ejemplo, por algún sistema automático.Un ejemplo de esto es este fragmento de enlace ASP.NET simple con el control Calendar:
Aquí,
SelectedDate
de hecho , es una propiedad, deDateTime
tipo, delCalendar
tipo Control web, y el enlace podría devolver algo nulo perfectamente. El Generador ASP.NET implícito creará un fragmento de código que será equivalente al código de transmisión anterior. Y esto generará un problemaNullReferenceException
que es bastante difícil de detectar, ya que se encuentra en el código generado por ASP.NET que se compila bien ...fuente
DateTime x = (DateTime) o as DateTime? ?? defaultValue;
Significa que la variable en cuestión no apunta a nada. Podría generar esto así:
Eso arrojará el error porque aunque he declarado la variable "
connection
", no apunta a nada. Cuando intento llamar al miembro "Open
", no hay ninguna referencia para resolverlo y arrojará el error.Para evitar este error:
object == null
.La herramienta Resharper de JetBrains identificará cada lugar en su código que tenga la posibilidad de un error de referencia nulo, lo que le permite realizar una verificación nula. Este error es la fuente número uno de errores, en mi humilde opinión.
fuente
Significa que su código utilizó una variable de referencia de objeto que se estableció en nulo (es decir, no hizo referencia a una instancia de objeto real).
Para evitar el error, los objetos que podrían ser nulos deben ser probados para nulo antes de ser utilizados.
fuente
Tenga en cuenta que, independientemente del escenario, la causa es siempre la misma en .NET:
fuente
Un ejemplo de esta excepción lanzada es: cuando intenta verificar algo, eso es nulo.
Por ejemplo:
El tiempo de ejecución de .NET generará una NullReferenceException cuando intente realizar una acción en algo que no se haya instanciado, es decir, el código anterior.
En comparación con una excepción ArgumentNullException que generalmente se lanza como una medida defensiva si un método espera que lo que se le pasa no sea nulo.
Más información está en C # NullReferenceException y Null Parameter .
fuente
Actualización C # 8.0, 2019: tipos de referencia anulables
C # 8.0 introduce tipos de referencia anulables y tipos de referencia no anulables . Tipos de referencia por lo que sólo admiten nulos deben ser evaluados para evitar una NullReferenceException .
Si no ha inicializado un tipo de referencia y desea establecer o leer una de sus propiedades, arrojará una NullReferenceException .
Ejemplo:
Simplemente puede evitar esto comprobando si la variable no es nula:
Para comprender completamente por qué se produce una NullReferenceException, es importante conocer la diferencia entre los tipos de valor y [tipos de referencia] [3].
Por lo tanto, si se trata de tipos de valores , NullReferenceExceptions no puede ocurrir. ¡Aunque debe mantenerse alerta al tratar con tipos de referencia !
Solo los tipos de referencia, como sugiere el nombre, pueden contener referencias o apuntar literalmente a nada (o 'nulo'). Mientras que los tipos de valor siempre contienen un valor.
Tipos de referencia (estos deben ser verificados):
Tipos de valor (simplemente puede ignorar estos):
fuente
Otro caso en el que
NullReferenceExceptions
puede suceder es el uso (incorrecto) delas
operador :Aquí,
Book
yCar
son tipos incompatibles; aCar
no se puede convertir / lanzar a aBook
. Cuando este lanzamiento falla,as
regresanull
. Usarmybook
después de esto causa aNullReferenceException
.En general, debe usar un yeso o
as
, de la siguiente manera:Si espera que la conversión de tipos siempre tenga éxito (es decir, sabe cuál debe ser el objeto antes de tiempo), entonces debe usar un molde:
Si no está seguro del tipo, pero desea intentar usarlo como un tipo específico, use
as
:fuente
Está utilizando el objeto que contiene la referencia de valor nulo. Entonces está dando una excepción nula. En el ejemplo, el valor de la cadena es nulo y, al verificar su longitud, se produjo la excepción.
Ejemplo:
El error de excepción es:
fuente
Si bien lo que causa un NullReferenceExceptions y los enfoques para evitar / solucionar dicha excepción se han abordado en otras respuestas, lo que muchos programadores aún no han aprendido es cómo depurar de forma independiente dichas excepciones durante el desarrollo.
En Visual Studio, esto suele ser fácil gracias al Visual Studio Debugger .
Primero, asegúrese de detectar el error correcto: consulte ¿Cómo permito romper en 'System.NullReferenceException' en VS2010? Nota 1
Luego, comience con la depuración (F5) o adjunte [el depurador VS] al proceso en ejecución . En ocasiones puede ser útil usar
Debugger.Break
, lo que le pedirá que inicie el depurador.Ahora, cuando se lanza la NullReferenceException (o no se controla), el depurador se detendrá (¿recuerda la regla establecida anteriormente?) En la línea en la que ocurrió la excepción. A veces el error será fácil de detectar.
Por ejemplo, en la siguiente línea, el único código que puede causar la excepción es si se
myString
evalúa como nulo. Esto se puede verificar mirando la Ventana de Observación o ejecutando expresiones en la Ventana Inmediata .En casos más avanzados, como los siguientes, deberá usar una de las técnicas anteriores (Watch o Windows Inmediato) para inspeccionar las expresiones para determinar si
str1
era nulo o sistr2
era nulo.Una vez que se ha localizado la excepción, generalmente es trivial razonar hacia atrás para descubrir dónde se introdujo [incorrectamente] el valor nulo:
Tómese el tiempo necesario para comprender la causa de la excepción. Inspeccione las expresiones nulas. Inspeccione las expresiones anteriores que podrían haber resultado en tales expresiones nulas. Agregue puntos de interrupción y avance por el programa según corresponda. Usa el depurador.
1 Si Break on Throws es demasiado agresivo y el depurador se detiene en un NPE en la biblioteca .NET o de terceros, se puede usar Break on User-Unledled para limitar las excepciones detectadas. Además, VS2012 presenta Just My Code, que recomiendo habilitar también.
fuente
Simon Mourier dio este ejemplo :
donde una conversión de unboxing (cast) de
object
(o de una de las clasesSystem.ValueType
oSystem.Enum
, o de un tipo de interfaz) a un tipo de valor (que no seaNullable<>
) en sí mismo proporciona elNullReferenceException
.En la otra dirección, una conversión de boxeo de una
Nullable<>
que tieneHasValue
igualfalse
a un tipo de referencia, puede dar unanull
referencia que luego puede conducir a aNullReferenceException
. El ejemplo clásico es:A veces el boxeo ocurre de otra manera. Por ejemplo con este método de extensión no genérico:
el siguiente código será problemático:
Estos casos surgen debido a las reglas especiales que el tiempo de ejecución usa al boxear
Nullable<>
instancias.fuente
Agregar un caso cuando el nombre de la clase para la entidad utilizada en el marco de la entidad es el mismo que el nombre de la clase para un archivo de código subyacente de formulario web.
Supongamos que tiene un formulario web Contact.aspx cuya clase de código subyacente es Contact y tiene un nombre de entidad Contact.
Luego, el siguiente código arrojará una NullReferenceException cuando llame a context.SaveChanges ()
En aras de la integridad de la clase DataContext
y clase de entidad de contacto. A veces, las clases de entidad son clases parciales, por lo que también puede ampliarlas en otros archivos.
El error ocurre cuando la entidad y la clase codebehind están en el mismo espacio de nombres. Para solucionar esto, cambie el nombre de la clase de entidad o la clase de código subyacente para Contact.aspx.
Razón Todavía no estoy seguro del motivo. Pero cada vez que cualquiera de la clase de entidad extenderá System.Web.UI.Page, se produce este error.
Para discusión, eche un vistazo a NullReferenceException en DbContext.saveChanges ()
fuente
Otro caso general en el que uno podría recibir esta excepción implica burlarse de las clases durante las pruebas unitarias. Independientemente del marco de simulación que se utilice, debe asegurarse de que todos los niveles apropiados de la jerarquía de clases se burlen correctamente. En particular, todas las propiedades de
HttpContext
deben burlar que hace referencia el código bajo prueba.Consulte " NullReferenceException lanzada al probar AuthorizationAttribute personalizado " para obtener un ejemplo algo detallado.
fuente
Tengo una perspectiva diferente para responder esto. Este tipo de respuestas "¿qué más puedo hacer para evitarlo? "
Cuando se trabaja en diferentes capas , por ejemplo en una aplicación MVC, un controlador necesita servicios para llamar a las operaciones comerciales. En tales escenarios, el Contenedor de inyección de dependencias se puede utilizar para inicializar los servicios para evitar la NullReferenceException . Eso significa que no necesita preocuparse por verificar nulos y simplemente llamar a los servicios desde el controlador como si siempre estuvieran disponibles (e inicializados) como un singleton o un prototipo.
fuente
En cuanto a "qué debo hacer al respecto" , puede haber muchas respuestas.
Una forma más "formal" de prevenir tales condiciones de error durante el desarrollo es aplicar el diseño por contrato en su código. Esto significa que necesita establecer invariantes de clase , y / o incluso precondiciones y postcondiciones de función / método en su sistema, durante el desarrollo.
En resumen, los invariantes de clase aseguran que habrá algunas restricciones en su clase que no serán violadas en el uso normal (y, por lo tanto, la clase no entrará en un estado inconsistente). Las condiciones previas significan que los datos proporcionados como entrada para una función / método deben seguir algunas restricciones establecidas y nunca violarlas, y las condiciones posteriores significan que una salida de función / método debe seguir las restricciones establecidas nuevamente sin violarlas nunca. Las condiciones del contrato nunca deben violarse durante la ejecución de un programa libre de errores, por lo tanto, el diseño por contrato se verifica en la práctica en modo de depuración, mientras se desactiva en las versiones , para maximizar el rendimiento del sistema desarrollado.
De esta manera, puede evitar
NullReferenceException
casos que son el resultado de la violación de las restricciones establecidas. Por ejemplo, si usa una propiedad de objetoX
en una clase y luego intenta invocar uno de sus métodos yX
tiene un valor nulo, esto conducirá aNullReferenceException
:Pero si establece "la propiedad X nunca debe tener un valor nulo" como condición previa del método, puede evitar el escenario descrito anteriormente:
Por esta causa, el proyecto de contratos de código existe para aplicaciones .NET.
Alternativamente, el diseño por contrato se puede aplicar utilizando aserciones .
ACTUALIZACIÓN: Vale la pena mencionar que el término fue acuñado por Bertrand Meyer en relación con su diseño del lenguaje de programación Eiffel .
fuente
Se
NullReferenceException
genera A cuando intentamos acceder a las Propiedades de un objeto nulo o cuando un valor de cadena se vacía y estamos intentando acceder a métodos de cadena.Por ejemplo:
Cuando se accede a un método de cadena de una cadena vacía:
Cuando se accede a una propiedad de un objeto nulo:
fuente
String.Empty.ToLower()
no lanzará una excepción de referencia nula. Representa una cadena real, aunque vacía (es decir""
). Como esto tiene un objeto al que invocarToLower()
, no tendría sentido lanzar una excepción de referencia nula allí.TL; DR: intente usar en
Html.Partial
lugar deRenderpage
Obtuve
Object reference not set to an instance of an object
cuando traté de representar una Vista dentro de una Vista enviándole un Modelo, como este:La depuración mostró que el modelo era Nulo dentro de MyOtherView. Hasta que lo cambié a:
Y funcionó.
Además, la razón por la que no tuve
Html.Partial
que comenzar fue porque Visual Studio a veces arroja líneas onduladas con aspecto de errorHtml.Partial
si está dentro de unforeach
bucle de construcción diferente , aunque en realidad no es un error:Pero pude ejecutar la aplicación sin problemas con este "error". Pude deshacerme del error cambiando la estructura del
foreach
bucle para que se vea así:Aunque tengo la sensación de que fue porque Visual Studio estaba leyendo mal los símbolos y los corchetes.
fuente
Html.Partial
, no@Html.Partial
Null
), así que sabía que el error estaba en cómo estaba enviando el Modelo.¿Qué puedes hacer al respecto?
Aquí hay muchas buenas respuestas que explican qué es una referencia nula y cómo depurarla. Pero hay muy poco sobre cómo prevenir el problema o al menos facilitar su detección.
Verificar argumentos
Por ejemplo, los métodos pueden verificar los diferentes argumentos para ver si son nulos y arrojar un
ArgumentNullException
, una excepción obviamente creada para este propósito exacto.El constructor para el
ArgumentNullException
par toma el nombre del parámetro y un mensaje como argumentos para que pueda decirle al desarrollador exactamente cuál es el problema.Usar herramientas
También hay varias bibliotecas que pueden ayudar. "Resharper", por ejemplo, puede proporcionarle advertencias mientras escribe código, especialmente si usa su atributo: NotNullAttribute
Hay "Contratos de código de Microsoft" donde usa una sintaxis como la
Contract.Requires(obj != null)
que le da tiempo de ejecución y compilación de verificación: Introducción de contratos de código .También hay "PostSharp" que le permitirá usar atributos como este:
Al hacer eso y hacer que PostSharp forme parte de su proceso de compilación
obj
, se verificará que no es nulo en tiempo de ejecución. Ver: verificación nula PostSharpSolución de código simple
O siempre puede codificar su propio enfoque utilizando un código antiguo simple. Por ejemplo, aquí hay una estructura que puede usar para capturar referencias nulas. Se basa en el mismo concepto que
Nullable<T>
:Usaría una forma muy similar a la misma que usaría
Nullable<T>
, excepto con el objetivo de lograr exactamente lo contrario: no permitirnull
. Aquí hay unos ejemplos:NotNull<T>
está implícitamente emitido hacia y desdeT
para que pueda usarlo en cualquier lugar donde lo necesite. Por ejemplo, puede pasar unPerson
objeto a un método que tome unNotNull<Person>
:Como puede ver arriba, como con nulable, accedería al valor subyacente a través de la
Value
propiedad. Alternativamente, puede usar una conversión explícita o implícita, puede ver un ejemplo con el valor de retorno a continuación:O incluso puede usarlo cuando el método simplemente regrese
T
(en este casoPerson
) haciendo un lanzamiento. Por ejemplo, al siguiente código le gustaría el código anterior:Combinar con extensión
Combine
NotNull<T>
con un método de extensión y puede cubrir incluso más situaciones. Aquí hay un ejemplo de cómo puede verse el método de extensión:Y aquí hay un ejemplo de cómo podría usarse:
GitHub
Para su referencia, hice que el código anterior esté disponible en GitHub, puede encontrarlo en:
https://github.com/luisperezphd/NotNull
Característica relacionada del lenguaje
C # 6.0 introdujo el "operador nulo-condicional" que ayuda un poco con esto. Con esta función, puede hacer referencia a objetos anidados y, si alguno de ellos es
null
la expresión completa, regresanull
.Esto reduce la cantidad de comprobaciones nulas que tiene que hacer en algunos casos. La sintaxis es poner un signo de interrogación antes de cada punto. Tome el siguiente código, por ejemplo:
Imagine que
country
es un objeto de tipoCountry
que tiene una propiedad llamadaState
y así sucesivamente. Sicountry
,State
,County
, oCity
esnull
entoncesaddress will be
nula. Therefore you only have to check whether
direcciónis
null`.Es una gran característica, pero le brinda menos información. No hace obvio cuál de los 4 es nulo.
¿Incorporado como Nullable?
C # tiene una buena abreviatura para
Nullable<T>
, puede hacer que algo sea anulable poniendo un signo de interrogación después del tipo de esta maneraint?
.Sería bueno si C # tenido algo así como la
NotNull<T>
estructura anterior y tenía una taquigrafía similares, tal vez el signo de exclamación para que usted podría escribir algo como (!):public void WriteName(Person! person)
.fuente
Curiosamente, ninguna de las respuestas en esta página menciona los dos casos extremos, espero que a nadie le importe si los agrego:
Caso límite # 1: acceso concurrente a un diccionario
Los diccionarios genéricos en .NET no son seguros para subprocesos y a veces pueden arrojar un
NullReference
o incluso (más frecuente) unKeyNotFoundException
cuando intenta acceder a una clave desde dos subprocesos simultáneos. La excepción es bastante engañosa en este caso.Caso de borde # 2: código inseguro
Si el código
NullReferenceException
arroja unaunsafe
, puede mirar las variables de puntero y verificar siIntPtr.Zero
o algo así. Lo que es lo mismo ("excepción de puntero nulo"), pero en el código inseguro, las variables a menudo se convierten en tipos / matrices de valores, etc., y te golpeas la cabeza contra la pared, preguntándote cómo un tipo de valor puede arrojar esto excepción.(Por cierto, otra razón para no usar código inseguro a menos que lo necesite)
fuente
null
qué manera?Puede arreglar NullReferenceException de manera limpia utilizando operadores condicional nulo en c # 6 y escribir menos código para manejar las comprobaciones nulas.
Se utiliza para probar nulo antes de realizar una operación de acceso de miembro (?.) O índice (? [).
Ejemplo
es equivalente a:
El resultado es que el nombre será nulo cuando p sea nulo o cuando p.Spouse sea nulo.
De lo contrario, al nombre de la variable se le asignará el valor de p.Spouse.FirstName.
Para más detalles: Operadores condicional nulo
fuente
La línea de error "Referencia de objeto no establecida en una instancia de un objeto" indica que no ha asignado un objeto de instancia a una referencia de objeto y que aún está accediendo a propiedades / métodos de ese objeto.
por ejemplo: supongamos que tiene una clase llamada myClass y contiene una propiedad prop1.
Ahora está accediendo a este prop1 en alguna otra clase, como a continuación:
la línea anterior arroja un error porque la referencia de la clase myClass se declara pero no se instancia o una instancia del objeto no se asigna a la referencia de esa clase.
Para solucionar esto, debe crear una instancia (asignar objeto a la referencia de esa clase).
fuente
NullReferenceException o la referencia de objeto no establecida en una instancia de un objeto se produce cuando un objeto de la clase que está intentando utilizar no se instancia. Por ejemplo:
Suponga que tiene una clase llamada Estudiante.
Ahora, considere otra clase en la que está tratando de recuperar el nombre completo del alumno.
Como se ve en el código anterior, la declaración Student s - solo declara la variable de tipo Student, tenga en cuenta que la clase Student no se instancia en este punto. Por lo tanto, cuando se ejecuta la instrucción s.GetFullName () , arrojará la NullReferenceException.
fuente
Bueno, en términos simples:
Está intentando acceder a un objeto que no está creado o que actualmente no está en la memoria.
Entonces, cómo abordar esto:
Depura y deja que el depurador se rompa ... Te llevará directamente a la variable que está rota ... Ahora tu tarea es simplemente solucionar esto ... Usando la nueva palabra clave en el lugar apropiado.
Si se produce en algunos comandos de la base de datos porque el objeto no está presente, entonces todo lo que necesita hacer es hacer una verificación nula y manejarlo:
El más difícil ... si el GC ya recolectó el objeto ... Esto generalmente ocurre si está tratando de encontrar un objeto usando cadenas ... Es decir, si lo encuentra por el nombre del objeto, puede suceder que el GC ya pueda lo limpió ... Esto es difícil de encontrar y se convertirá en un gran problema ... Una mejor manera de abordar esto es realizar comprobaciones nulas siempre que sea necesario durante el proceso de desarrollo. Esto te ahorrara mucho tiempo.
Al encontrar por nombre me refiero a que algún marco le permite FIndObjects usando cadenas y el código podría verse así: FindObject ("ObjectName");
fuente
Literalmente, la forma más fácil de arreglar una NullReferenceExeption tiene dos formas. Si tiene un GameObject, por ejemplo, con un script adjunto y una variable llamada rb (cuerpo rígido), esta variable comenzará nula cuando inicie el juego.
Es por eso que obtiene una NullReferenceExeption porque la computadora no tiene datos almacenados en esa variable.
Usaré una variable RigidBody como ejemplo.
Podemos agregar datos realmente fácilmente de varias maneras:
Luego ingrese a su script y escriba
rb = GetComponent<Rigidbody>();
Esta línea de código funciona mejor bajo sus funciones
Start()
oAwake()
.rb = AddComponent<RigidBody>();
Notas adicionales: Si desea la unidad para agregar un componente a su objeto y puede haber olvidado agregar uno, puede escribir
[RequireComponent(typeof(RigidBody))]
arriba de su declaración de clase (el espacio debajo de todos sus usos).¡Disfruta y diviértete haciendo juegos!
fuente
Si consideramos escenarios comunes donde se puede lanzar esta excepción, accedemos a las propiedades dentro del objeto en la parte superior.
Ex:
aquí, si la dirección es nula, obtendrá NullReferenceException.
Por lo tanto, como práctica, siempre debemos usar la verificación nula, antes de acceder a las propiedades de dichos objetos (especialmente en genéricos)
fuente
Esto es básicamente una excepción de referencia nula . Como Microsoft Unidos-
Qué significa eso?
Eso significa que si algún miembro que no tiene ningún valor y estamos haciendo que ese miembro realice cierta tarea, el sistema indudablemente arrojará un mensaje y dirá:
"Oye, espera, ese miembro no tiene valores, por lo que no puede realizar la tarea que le estás entregando".
La excepción en sí dice que se está refiriendo algo pero cuyo valor no se está estableciendo. Esto denota que solo ocurre mientras se usan tipos de referencia, ya que los tipos de Valor no son anulables.
NullReferenceException no ocurrirá si estamos utilizando miembros de tipo Value.
El código anterior muestra una cadena simple que se asigna con un valor nulo .
Ahora, cuando intento imprimir la longitud de la cadena str , recibo un mensaje de excepción no controlada del tipo 'System.NullReferenceException' porque el miembro str apunta a nulo y no puede haber ninguna longitud nula.
' NullReferenceException ' también ocurre cuando olvidamos instanciar un tipo de referencia.
Supongamos que tengo una clase y un método miembro. No he instanciado mi clase, sino que solo he nombrado mi clase. Ahora, si trato de usar el método, el compilador arrojará un error o emitirá una advertencia (dependiendo del compilador).
El compilador para el código anterior genera un error de que la variable obj no está asignada, lo que significa que nuestra variable tiene valores nulos o nada. El compilador para el código anterior genera un error de que la variable obj no está asignada, lo que significa que nuestra variable tiene valores nulos o nada.
¿Por qué ocurre?
NullReferenceException surge debido a nuestra culpa por no verificar el valor del objeto. A menudo dejamos los valores del objeto sin marcar en el desarrollo del código.
También surge cuando olvidamos instanciar nuestros objetos. El uso de métodos, propiedades, colecciones, etc. que pueden devolver o establecer valores nulos también puede ser la causa de esta excepción.
¿Cómo se puede evitar?
Hay varias formas y métodos para evitar esta reconocida excepción:
Comprobación explícita: debemos cumplir con la tradición de comprobar los objetos, propiedades, métodos, matrices y colecciones si son nulos. Esto se puede implementar simplemente usando declaraciones condicionales como if-else if-else, etc.
Manejo de excepciones: una de las formas importantes de gestionar esta excepción. Usando simples bloques try-catch-finally podemos controlar esta excepción y también mantener un registro de la misma. Esto puede ser muy útil cuando su aplicación está en etapa de producción.
Operadores nulos: el operador de fusión nula y los operadores condicionales nulos también se pueden usar a la vez que se configuran valores para objetos, variables, propiedades y campos.
Depurador: para los desarrolladores, tenemos el gran arma de la depuración con nosotros. Si nos enfrentamos a NullReferenceException durante el desarrollo, podemos usar el depurador para llegar al origen de la excepción.
Método incorporado: los métodos del sistema como GetValueOrDefault (), IsNullOrWhiteSpace () e IsNullorEmpty () comprueban nulos y asignan el valor predeterminado si hay un valor nulo.
Ya hay muchas buenas respuestas aquí. También puede consultar una descripción más detallada con ejemplos en mi blog .
Espero que esto ayude también!
fuente
Si uno recibe este mensaje durante el guardado o la compilación de la compilación, simplemente cierre todos los archivos y luego abra cualquier archivo para compilar y guardar.
Para mí, la razón era que había cambiado el nombre del archivo y el archivo antiguo todavía estaba abierto.
fuente