The*_*Fox 32 c# null nullreferenceexception
我知道一开始这似乎是不可能的,一开始对我来说也是如此,但最近我看到了这种代码抛出 a NullReferenceException,所以这绝对是可能的。
不幸的是,Google 上几乎没有任何结果可以解释诸如此类的代码何时foo == null会引发 NRE,这会使调试和理解其发生的原因变得困难。因此,为了记录这种看似奇怪的事件可能发生的可能方式。
这段代码可以以什么方式foo == null抛出NullReferenceException?
Jon*_*lis 38
在 C# 中,您可以重载运算符以在这样的比较中添加自定义逻辑。例如:
class Test
{
public string SomeProp { get; set; }
public static bool operator ==(Test test1, Test test2)
{
return test1.SomeProp == test2.SomeProp;
}
public static bool operator !=(Test test1, Test test2)
{
return !(test1 == test2);
}
}
Run Code Online (Sandbox Code Playgroud)
那么这将产生一个空引用异常:
Test test1 = null;
bool x = test1 == null;
Run Code Online (Sandbox Code Playgroud)
小智 16
一个例子是 getter:
class Program
{
static void Main(string[] args)
{
new Example().Test();
}
}
class Example
{
private object foo
{
get => throw new NullReferenceException();
}
public void Test()
{
Console.WriteLine(foo == null);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码将产生 NullReferenceException。
虽然相当深奥,但有可能通过DynamicMetaObject. 这将是可能发生这种情况的一个罕见但有趣的例子:
void Main()
{
dynamic foo = new TestDynamicMetaObjectProvider();
object foo2 = 0;
Console.WriteLine(foo == foo2);
}
public class TestDynamicMetaObjectProvider : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new TestMetaObject(parameter, BindingRestrictions.Empty, this);
}
}
public class TestMetaObject : DynamicMetaObject
{
public TestMetaObject(Expression expression, BindingRestrictions restrictions)
: base(expression, restrictions)
{
}
public TestMetaObject(Expression expression, BindingRestrictions restrictions, object value)
: base(expression, restrictions, value)
{
}
public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
{
// note it doesn't have to be an explicit throw. Any improper property
// access could bubble a NullReferenceException depending on the
// custom implementation.
throw new NullReferenceException();
}
}
Run Code Online (Sandbox Code Playgroud)
不是字面上的代码,但等待空任务也会抛出:
public class Program
{
public static async Task Main()
{
var s = ReadStringAsync();
if (await s == null)
{
Console.WriteLine("s is null");
}
}
// instead of Task.FromResult<string>(null);
private static Task<string> ReadStringAsync() => null;
}
Run Code Online (Sandbox Code Playgroud)
但是请注意,调试器可能会错误地获取抛出语句的位置。它可能会显示在相等检查中抛出的异常,而它发生在早期代码中。
| 归档时间: |
|
| 查看次数: |
2581 次 |
| 最近记录: |