我有一些代码,当它执行时,抛出了一个 NullReferenceException
异常,显示:
对象引用未设置为对象的实例。
这是什么意思?我该如何修复此错误?
我有一些代码,当它执行时,抛出了一个 NullReferenceException
异常,显示:
对象引用未设置为对象的实例。
这是什么意思?我该如何修复此错误?
有趣的是,本页上的答案中没有提到两个极端情况:
.NET中的通用字典不是线程安全的,当您尝试从两个并发线程访问键时,它们有时可能会抛出NullReference
(空引用)或甚至更频繁地抛出KeyNotFoundException
(找不到键),此时异常信息非常具有误导性。
如果unsafe
代码抛出了NullReferenceException
,您可能需要查看指针变量,并检查它们是否为IntPtr.Zero
或类似内容。这与“空指针异常”相同,但在不安全的代码中,变量经常被转换为值类型/数组等,您会不停地碰壁,不知道为什么值类型会引发此异常。
(顺便说一下,这也是不需要时最好不使用不安全代码的另一个原因。)
此边缘情况与特定软件相关,涉及到Visual Studio 2019集成开发环境(IDE)(以及可能的早期版本)。
复现此问题的方法:将工具箱中的任何组件拖到具有与主监视器不同DPI设置的非主监视器上的Windows表单中,就会弹出“对象未设置为对象实例”的弹出窗口。根据这个线程,这个问题已经存在了相当长的时间,而在撰写本文时,它仍未被修复。
null
有何区别? - John Saunders“Object reference not set to an instance of an object.”的错误行指出您尚未将实例对象分配给对象引用,但仍在访问该对象的属性/方法。
例如:假设您有一个名为myClass的类,它包含一个属性prop1。
public Class myClass
{
public int prop1 {get;set;}
}
现在您可以像下面这样在其他类中访问此prop1:
public class Demo
{
public void testMethod()
{
myClass ref = null;
ref.prop1 = 1; // This line throws an error
}
}
由于声明了 myClass 类的引用,但未创建实例或未将对象的实例分配给该类的引用,因此上述代码会抛出错误。
要解决此问题,您需要实例化(将一个对象分配给该类的引用)。
public class Demo
{
public void testMethod()
{
myClass ref = null;
ref = new myClass();
ref.prop1 = 1;
}
}
简单来说:
你正在尝试访问一个未被创建或当前不在内存中的对象。
那么如何解决这个问题:
Debug and let the debugger break... It will directly take you to the variable that is broken... Now your task is to simply fix this.. Using the new keyword in the appropriate place.
If it is caused on some database commands because the object isn't present then all you need to do is do a null check and handle it:
if (i == null) {
// Handle this
}
The hardest one .. if the GC collected the object already... This generally occurs if you are trying to find an object using strings... That is, finding it by name of the object then it may happen that the GC might already cleaned it up... This is hard to find and will become quite a problem... A better way to tackle this is do null checks wherever necessary during the development process. This will save you a lot of time.
所谓按名称查找,是指某些框架允许您使用字符串查找对象,代码可能如下所示:FindObject("ObjectName");
当你尝试使用一个未实例化的类的对象时,就会出现NullReferenceException或Object reference not set to an instance of an object错误。
例如:
假设你有一个名为Student的类。
public class Student
{
private string FirstName;
private string LastName;
public string GetFullName()
{
return FirstName + LastName;
}
}
public class StudentInfo
{
public string GetStudentName()
{
Student s;
string fullname = s.GetFullName();
return fullname;
}
}
rb = GetComponent<Rigidbody>();
这行代码最好在您的Start()
或Awake()
函数下使用。rb = AddComponent<RigidBody>();
进一步说明:如果你想让Unity向你的对象添加一个组件,但可能忘记了添加一个,你可以在类声明之前(所有using下面的空格)键入[RequireComponent(typeof(RigidBody))]
。如果在保存或编译构建过程中出现此消息,请关闭所有文件,然后打开任何文件进行编译和保存。
对我来说,原因是我已经重命名了文件,但旧文件仍然处于打开状态。
这基本上是一个空引用异常。正如Microsoft所述-
当您尝试访问值为null的类型的成员时,将引发NullReferenceException异常。
这意味着如果任何成员没有任何值,并且我们让该成员执行某些任务,那么系统无疑会抛出一条消息并说-
“等等,该成员没有值,因此无法执行您交给它的任务。”
异常本身表明正在引用某些内容,但其值未被设置。因此,这表示仅在使用引用类型时才会发生,因为值类型是不可为空的。
如果我们使用值类型成员,则不会发生NullReferenceException。
class Program
{
static void Main(string[] args)
{
string str = null;
Console.WriteLine(str.Length);
Console.ReadLine();
}
}
以上代码显示了一个简单的字符串,它被赋予了null值。
现在,当我尝试打印字符串str的长度时,我会得到发生了未处理的异常类型‘System.NullReferenceException’的消息,因为成员str指向null,而null没有任何长度。
当我们忘记实例化引用类型时,也会发生‘NullReferenceException’。
假设我有一个类和其中的成员方法。我没有实例化我的类,只是给我的类命名。现在,如果我尝试使用这个方法,编译器将抛出一个错误或发出一个警告(取决于编译器)。
class Program
{
static void Main(string[] args)
{
MyClass1 obj;
obj.foo(); // Use of unassigned local variable 'obj'
}
}
public class MyClass1
{
internal void foo()
{
Console.WriteLine("Hello from foo");
}
}
NullReferenceException是由于我们没有检查对象的值而引起的错误。在代码开发中,我们经常不检查对象的值。
当我们忘记实例化对象时,也会出现这种情况。使用可能返回或设置null值的方法、属性、集合等也可能是这个异常的原因。
有各种方法可以避免这个著名的异常:
显式检查:我们应该遵循检查对象、属性、方法、数组和集合是否为空的传统。这可以通过使用条件语句如if-else if-else等来简单实现。
异常处理:管理此异常的重要方法之一是使用简单的try-catch-finally块,我们可以控制此异常并维护其日志。当您的应用程序处于生产阶段时,这非常有用。
空操作符:在为对象、变量、属性和字段设置值时,空合并运算符和空条件运算符也可以派上用场。
调试器:对于开发人员,我们拥有强大的调试武器。如果在开发过程中遇到NullReferenceException,我们可以使用调试器找到异常源头。
内置方法:系统方法如GetValueOrDefault()、IsNullOrWhiteSpace()和IsNullOrEmpty()检查null并在存在null值时分配默认值。
这里已经有很多好的答案了。你也可以在我的博客上查看更详细的描述和示例。
希望这也能帮到你!