C# 如何在特定类的NullReferenceException上自动引发自定义异常?
然后在这个场景中,null被传递给FeedDog() 我如何做才能使它在不这样做的情况下抛出C# 如何在特定类的NullReferenceException上自动引发自定义异常?,c#,.net,C#,.net,然后在这个场景中,null被传递给FeedDog() 我如何做才能使它在不这样做的情况下抛出dogdesnotexistexception public void FeedDog(Dog dog) { Console.WriteLine("Feeding "+dog.Name); // throws NullReferenceException } 所以当你这么做的时候 public void FeedDog(Dog dog) { if (dog == null)
dogdesnotexistexception
public void FeedDog(Dog dog)
{
Console.WriteLine("Feeding "+dog.Name); // throws NullReferenceException
}
所以当你这么做的时候
public void FeedDog(Dog dog)
{
if (dog == null)
throw new DogDoesNotExistException(); // want to get rid of this
Console.WriteLine("Feeding "+dog.Name);
}
一种方法是捕获错误并从中重新抛出,但这会影响每个类 因此,您应该考虑使用AOP(请参阅) 例如,如果您正在使用依赖项注入,那么可以使用拦截器 这个附加类将包装每个方法调用。重试捕获逻辑和重新抛出can站点。如果您真的想这样做,我建议将原始异常添加为内部异常 如果您正在使用MVC,那么还可以使用过滤器属性
尽管如此,我还是会小心地捕获像这样的Null Ref错误,因为它们非常通用 一种方法是捕获错误并从中重新抛出,但这会影响每个类 因此,您应该考虑使用AOP(请参阅) 例如,如果您正在使用依赖项注入,那么可以使用拦截器 这个附加类将包装每个方法调用。重试捕获逻辑和重新抛出can站点。如果您真的想这样做,我建议将原始异常添加为内部异常 如果您正在使用MVC,那么还可以使用过滤器属性
尽管如此,我还是会小心地捕获像这样的Null Ref错误,因为它们非常通用 在将
null
传递给FeedDog
时,不应抛出dogdesnotexistexception
。检查null
并抛出ArgumentNullException
以表明FeedDog
使用不正确,或者如果该方法用于无论如何都应该存在dog实例的上下文中,则根本不检查它
如果你没有养狗的话,你就不会去你的柜子里拿出狗粮放在碗里。如果你已经知道你有一只狗,你才会得到和准备食物
因此,如果你没有狗(dog
beingnull
),你就不会调用FeedDog
)。相反,您应该首先确保狗存在:
public void FeedDog(Dog dog)
{
try
{
Console.WriteLine("Feeding " + dog.Name);
}
catch(NullReferenceException e)
{
throw new DogDoesnotExistException();
}
}
将
null
传递给FeedDog
时,不应抛出dogdesnotexistException
。检查null
并抛出ArgumentNullException
以表明FeedDog
使用不正确,或者如果该方法用于无论如何都应该存在dog实例的上下文中,则根本不检查它
如果你没有养狗的话,你就不会去你的柜子里拿出狗粮放在碗里。如果你已经知道你有一只狗,你才会得到和准备食物
因此,如果你没有狗(dog
beingnull
),你就不会调用FeedDog
)。相反,您应该首先确保狗存在:
public void FeedDog(Dog dog)
{
try
{
Console.WriteLine("Feeding " + dog.Name);
}
catch(NullReferenceException e)
{
throw new DogDoesnotExistException();
}
}
我不明白为什么需要这样做,但一种方法是使用一个包装对象的结构,并将结构作为方法参数传递 有一个例子:
var dog = GetDogFromSomewhere();
if (dog == null)
{
throw new DogDoesNotExistException();
}
FeedDog(dog);
隐式强制转换运算符允许您以相同的方式调用该方法:
public void FeedDog(DogWrapper dog)
{
Console.WriteLine("Feeding "+dog.Name); // now throws DogDoesNotExistException
}
我不明白为什么需要这样做,但一种方法是使用一个包装对象的结构,并将结构作为方法参数传递 有一个例子:
var dog = GetDogFromSomewhere();
if (dog == null)
{
throw new DogDoesNotExistException();
}
FeedDog(dog);
隐式强制转换运算符允许您以相同的方式调用该方法:
public void FeedDog(DogWrapper dog)
{
Console.WriteLine("Feeding "+dog.Name); // now throws DogDoesNotExistException
}
另一种方法是避免到处使用null,而是创建一个名为“EmptyDog”的派生类,该类在任何属性访问时抛出异常
Dog dog = GetDog();
FeedDog(dog);
在Dog类中为此创建一个单例:
public class EmptyDog : Dog
{
public override Name {get { throw new DogDoesNotExistException(); } }
...
}
现在,您可以在任何地方使用这个EmptyDog而不是null Dog,或者您可以用一行防止null,然后在有人试图调用该Dog的名字时,依靠属性重写抛出异常
e、 g
请参阅。另一种方法是避免到处使用null,而是创建一个名为“EmptyDog”的派生类,该类在任何属性访问时抛出异常
Dog dog = GetDog();
FeedDog(dog);
在Dog类中为此创建一个单例:
public class EmptyDog : Dog
{
public override Name {get { throw new DogDoesNotExistException(); } }
...
}
现在,您可以在任何地方使用这个EmptyDog而不是null Dog,或者您可以用一行防止null,然后在有人试图调用该Dog的名字时,依靠属性重写抛出异常
e、 g
请参阅。
GetDog
应引发异常。这是一个糟糕的设计。在此类中,并非所有NullReferenceException
都应转换为DogDoesNotExistException
。这很容易出错。你需要直言不讳。您真的需要抛出异常吗?如果原因是异常冒泡并在不同的层上处理,那么OK,但为什么不使用TryXXX模式返回布尔值?好的,我将更新我的问题您不能这样做。你没有这种程度的控制。异常是在CLR的内部深处生成的。作为比较,他们只是想找出哪个变量是导致NREs的原因,在未来版本的C#@Damien_中,如果你回答下面的问题,我可以接受你的答案GetDog
应该抛出异常。这是一个糟糕的设计。在此类中,并非所有NullReferenceException
都应转换为DogDoesNotExistException
。这很容易出错。你需要直言不讳。您真的需要抛出异常吗?如果原因是异常冒泡并在不同的层上处理,那么OK,但为什么不使用TryXXX模式返回布尔值?好的,我将更新我的问题您不能这样做。你没有这种程度的控制。异常是在系统的内部深处生成的