提问人:developer 提问时间:6/21/2011 最后编辑:Peter Mortensendeveloper 更新时间:9/11/2023 访问量:1265785
在 C 中检查对象是否为 null#
Checking if an object is null in C#
问:
如果对象为 null,我想阻止对对象进行进一步处理。
在下面的代码中,我通过以下任一方式检查对象是否为 null:
if (!data.Equals(null))
和
if (data != null)
但是,我收到一个 at .如果对象为 null,它甚至不应该输入 -语句!NullReferenceException
dataList.Add(data)
if
因此,我问这是否是检查对象是否为 null 的正确方法:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
如果这是检查对象是否为 null 的正确方法,我做错了什么(如何防止对对象进行进一步处理以避免 NullReferenceException)?
答:
你的 dataList 是 null,因为它没有被实例化,从你发布的代码来看。
尝试:
public List<Object> dataList = new List<Object>();
public bool AddData(ref Object data)
bool success = false;
try
{
if (!data.Equals(null)) // I've also used if(data != null) which hasn't worked either
{
dataList.Add(data); //NullReferenceException occurs here
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw;
}
return success;
}
评论
不是那样,而是.data
null
dataList
您需要创建一个
public List<Object> dataList = new List<Object>();
更好的是:既然它是一个领域,那就让它.如果没有什么能阻止你,那就让它也成为.只是好的做法。private
readonly
旁白
检查无效的正确方法是 。这种检查对于引用类型是无处不在的;甚至会覆盖相等运算符,以便在检查无效时成为更方便的表达方式。if(data != null)
Nullable<T>
nullable.HasValue
如果你这样做,那么你会得到一个 if .这有点滑稽,因为避免这个例外是首先的目标。if(!data.Equals(null))
NullReferenceException
data == null
您也在这样做:
catch (Exception e)
{
throw new Exception(e.ToString());
}
这绝对不好。我可以想象你把它放在那里只是为了让你可以在方法内部闯入调试器,在这种情况下,忽略这一段。否则,不要无缘无故地捕获异常。如果你这样做了,只需使用 .throw;
评论
null != data
null = data
==
if (data = null)
NullReferenceException
null
.
datalist.Add(data)
datalist
datalist.Add(data.Value)
datalist
data
在这种情况下,问题不在于 null。它本身就是空的。data
dataList
在声明的位置,您应该创建一个新对象并将其分配给变量。dataList
List
List<object> dataList = new List<object>();
不,您应该使用 .如果实际上为 null,则由于尝试调用 上的方法,您的程序将崩溃并显示 。还要注意,如果你特别想检查引用是否相等,你应该使用该方法,因为你永远不知道是如何实现的。!=
data
NullReferenceException
Equals
null
Object.ReferenceEquals
Equals
您的程序正在崩溃,因为您从未初始化它,因此为 null。dataList
杰弗里·惠特利奇(Jeffrey L Whitledge)是对的。你的 'dataList'-Object 本身是 null。
您的代码还存在另一个问题:您正在使用 ref-keyword,这意味着参数 data 不能为 null!MSDN 说:
必须首先初始化传递给 ref 参数的参数。这与 out 不同,out 的参数在传递之前不必显式初始化
使用类型为“Object”的泛型也不是一个好主意。泛型应避免装箱/拆箱,并确保类型安全。如果需要通用类型,请使方法泛型。最后,您的代码应如下所示:
public class Foo<T> where T : MyTypeOrInterface {
public List<T> dataList = new List<T>();
public bool AddData(ref T data) {
bool success = false;
try {
dataList.Add(data);
success = doOtherStuff(data);
} catch (Exception e) {
throw new Exception(e.ToString());
}
return success;
}
private bool doOtherStuff(T data) {
//...
}
}
正如其他人已经指出的那样,事实并非如此,而是很可能如此。除此之外...data
dataList
null
catch
-throw
是一种反模式,几乎总是让我每次看到它都想吐。想象一下,在召唤的东西深处出了点问题。你得到的只是一个物体,扔在里面。没有堆栈跟踪,没有调用信息,没有状态,根本没有任何东西来指示问题的真正根源,除非你进入并切换调试器以在引发异常时中断,而不是在未处理异常时中断。如果你捕捉到一个异常,并以任何方式重新抛出它,特别是如果try块中的代码在任何方面都是非平凡的,请帮你自己(以及你的同事,现在和将来)一个忙,扔掉整个-块。诚然,它比其他选择要好,但你仍然给自己(或其他任何试图修复代码中的错误的人)带来完全不必要的麻烦。这并不是说 try-catch-throw 本身一定是邪恶的,只要你对 catch 块中抛出的异常对象做了一些相关的事情。doOtherStuff()
Exception
throw
AddData()
try
catch
throw;
然后是首先捕获的潜在问题,但这是另一回事,特别是因为在这种特殊情况下,你会抛出异常。Exception
另一件让我印象深刻的事情是,在函数执行期间可能会更改值,因为您是通过引用传递的。因此,null 检查可能会通过,但在代码对该值执行任何操作之前,它已更改 - 可能更改为 .我不确定这是否是一个问题(可能不是),但似乎值得关注。data
null
[编辑以反映@kelton52的提示]
最简单的方法就是去做object.ReferenceEquals(null, data)
由于不能保证工作:(null==data)
class Nully
{
public static bool operator ==(Nully n, object o)
{
Console.WriteLine("Comparing '" + n + "' with '" + o + "'");
return true;
}
public static bool operator !=(Nully n, object o) { return !(n==o); }
}
void Main()
{
var data = new Nully();
Console.WriteLine(null == data);
Console.WriteLine(object.ReferenceEquals(null, data));
}
生产:
比较 '' 和 'Nully'
真
假
评论
C# 6 具有 monadic null 检查:)
以前:
if (points != null) {
var next = points.FirstOrDefault();
if (next != null && next.X != null) return next.X;
}
return -1;
后:
var bestValue = points?.FirstOrDefault()?.X ?? -1;
评论
result = myObject == null ? null : myObject.SomeProperty
result = myObject?.SomeProperty
public static bool isnull(object T)
{
return T == null ? true : false;
}
用:
isnull(object.check.it)
有条件使用:
isnull(object.check.it) ? DoWhenItsTrue : DoWhenItsFalse;
更新(另一种方式)更新于 2017 年 8 月 31 日和 2021 年 1 月 25 日。谢谢你的评论。
public static bool IsNull(object T)
{
return (bool)T ? true : false;
}
为了记录,你在 Github 上有我的代码,去看看: https://github.com/j0rt3g4/ValidateNull PS:这个特别适合你 Chayim Friedman,不要使用测试版软件假设这一切都是真的。等待最终版本或使用您自己的环境进行测试,然后再假设真正的测试版软件,而无需您提供任何文档或演示。
评论
cond ? true : false;
完全等同于.这不会增加任何内容。cond
return T == null;
return T == null ? true : false;
return T == null;
return T ? true : false;
true
T
null
public static bool IsNull(this object T)
{
return T == null;
}
并对所有对象使用方法,例如:IsNull
object foo = new object(); //or any object from any class
if (foo.IsNull())
{
// blah blah //
}
评论
return T == null ? true : false;
return T == null;
每当您创建类对象时,您都必须使用以下代码检查对象是否为 null。
例: object1 是类的对象
void myFunction(object1)
{
if(object1!=null)
{
object1.value1 //If we miss the null check then here we get the Null Reference exception
}
}
用if (obj is null)
对于非 null,请使用:
或
(C# > 9)if (obj is object)
if (obj is not null)
这些将忽略对象定义的任何或定义(当然,除非您想将它们用于 null 检查)==
!=
有关详细信息,请参阅《C# 语言参考》中的 is 运算符。
评论
obj is not null
)
if (obj aint null)
if (obj is object)
IsNot
And
Or
我只是遵循了我们通常在 java 脚本中遵循的方法。将对象转换为字符串,然后检查它们是否为 null。
var obj = new Object();
var objStr = obj.ToString();
if (!string.IsNullOrEmpty(objStr)){
// code as per your needs
}
从 C# 8 开始,可以使用“空”属性模式(具有模式匹配)来确保对象不为 null:
if (obj is { })
{
// 'obj' is not null here
}
这种方法的意思是“如果对象引用了某物的实例”(即它不是 null)。
您可以将其视为以下的反义词。当对象不引用某物的实例时,它将返回 true。if (obj is null)...
有关 C# 8.0 中的模式的详细信息,请阅读此处。
评论
!= null
ldloc.0; ldnull; cgt.un
!= null
!= null
!=
object
我做了更简单(积极的方式),它似乎效果很好。
因为任何一种“对象”至少都是一个对象
if (MyObj is Object)
{
//Do something .... for example:
if (MyObj is Button)
MyObj.Enabled = true;
}
从 C# 9 开始,您可以执行以下操作
if (obj is null) { ... }
对于非 null 使用
if (obj is not null) { ... }
如果需要覆盖此行为,请相应地使用 和。==
!=
使用 c#9 (2020),您现在可以使用以下代码检查参数是否为 null:
if (name is null) { }
if (name is not null) { }
你可以在这里获得更多信息
您可以尝试如下
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
if (data != null)
{
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
以下是我使用的一些扩展:
/// <summary>
/// Extensions to the object class
/// </summary>
public static class ObjectExtensions
{
/// <summary>
/// True if the object is null, else false
/// </summary>
public static bool IsNull(this object input) => input is null;
/// <summary>
/// False if the object is null, else true
/// </summary>
public static bool NotNull(this object input) => !IsNull(input);
}
public bool IsVisible(object ClaimCount)
{
bool flag = true;
#region || HIDE COLUMNS ON CONDITION BASIS
if (!String.IsNullOrEmpty(Convert.ToString(ClaimCount)))
{
Int32 ClaimCnt = Convert.ToInt32(ClaimCount);
if (ClaimCnt == 1)
{
flag = false;
}
}
#endregion
return flag;
}
评论
.NET 6 中有一个单行代码
ExampleMethod(null);
void ExampleMethod(object param)
{
ArgumentNullException.ThrowIfNull(param);
// Do something
}
评论
throw e;
throw new Exception(e.ToString());
!= null
.Equals
throw e;
throw;
e.ToString()
InnerExceptions
throw;