如何为'float方法返回null '-错误处理
本文关键字:null 处理 错误 返回 float 方法 | 更新日期: 2023-09-27 18:12:51
我想在我的代码中添加一些错误处理。对于下面的例子,我想不出该怎么做:
public class DataPoints
{
public PointF[] RawData {get; set;} //raw measurement pairs
public float xMax; //max value on X axis
public float yMax; //max value on Y axis
public float GetMaxX()
{
if(RawData == null)
{
throw new NullReferenceException();
return null; //THIS does not compile! I want to exit the method here
}
//DO other stuff to find max X
return MAX_X; //as float
}
}
所以我的想法是,我需要检查RawData
是否已经设置,然后在GetMaxX()
方法中做其余的事情。这是一个好的实践吗?在这种情况下你会怎么做?
这段代码有两个问题,
首先抛出一个异常,然后是一个return——return语句永远不会被执行,因为异常会停止执行方法的其余部分,使得return语句变得多余。
其次,当返回类型为float时,不能返回null;你需要将返回类型改为浮点数吗?(参见:nullable types)
所以,如果这是一个真正的错误情况,因为没有什么可以做的,只使用异常:
public float GetMaxX()
{
if(RawData == null)
throw new NullReferenceException();
//DO other stuff to find max X
return MAX_X; //as float
}
或者,返回null并删除异常:
public float? GetMaxX()
{
if(RawData == null)
return null;
//DO other stuff to find max X
return MAX_X; //as float
}
就我个人而言,如果RawData
为空是一个错误条件/异常情况,不应该发生,那么我会说抛出异常,并处理异常,如果在调用代码中抛出。
另一种方法是通过构造函数强制初始化RawData
,使RawData
为私有(或至少是setter)并在那里抛出异常。使类内的任何其他逻辑清除任何异常抛出/空检查,因为它可以假设RawData
先前已设置。
产生如下内容:
public class DataPoints
{
private readonly PointF[] rawData; //raw measurement pairs
public float xMax; //max value on X axis
public float yMax; //max value on Y axis
public DataPoints(PointF[] rawData)
{
if (rawData == null)
throw new ArgumentNullException("rawData");
this.rawData = rawData;
}
public float GetMaxX()
{
//DO other stuff to find max X
return MAX_X; //as float
}
}
如果你抛出一个异常,返回语句将不会被执行,所以你尝试的正确版本应该是
public float GetMaxX()
{
if(RawData == null)
{
throw new NullReferenceException();
}
//DO other stuff to find max X
return MAX_X; //as float
}
返回语句不会编译,因为float是一种值类型,它永远不会为空,除非你使用可空类型float?
我个人从你给的代码样本,我会抛出异常,因为你目前通过一个公共设置器暴露RawData对象,所以你不能保证它不会是空的,当GetMaxX被调用。然后异常可以在堆栈中传播并在任何级别被捕获,而通过使返回类型为空,您将不得不向调用代码添加额外的检查,以查看您的方法是否返回null并适当地处理。
我不清楚在错误的情况下你想做什么。是要抛出异常还是返回null?
一般来说,抛出异常是为了当调用者应该知道得更好,而你不想尝试恢复-让调用者清理混乱。
返回null用于调用者可能有很好的理由不初始化RawData时,这在您的情况下是有意义的。为此你需要有
public float? GetMaxX()
可以删除throw异常语句下面的返回语句。每当抛出异常时,方法中不会执行任何其他语句(finally块是this的异常,但与此上下文中无关)。
除了这个关于函数的问题,我有一个关于RawData属性被公开访问的参数。一般来说,像那样打开一个收藏不是一个好主意。正如@sq33G所建议的,您可以通过将RawData作为构造函数参数传递来保证拥有一个有效的对象。当传入一个无效数组(null,可能大小为0 ?)时,您可能会在构造函数的早期失败。
private PointF[] _rawData;
public DataPoints(PointF[] rawData)
{
if(rawData == null || rawData.Length == 0)
throw new ArgumentException("RawData should not be null and should contain at least one element");
this._rawData = rawData;
}
如果有必要从类外部访问RawSata,我建议您以一种既不能改变数组本身(因此没有setter)也不能改变其内容的方式进行。使用IEnumerable是一种正确的方法。
public IEnumerable<PointF> RawData
{
get { return _rawData; }
}
方法并不总是需要返回值;特别是,它也被允许退出抛出异常(在这种情况下不返回任何值)。你可以查看规则
在你的例子中,你可以
(a)引发一个NullReferenceException——这将打破流并返回
(b)返回默认值,如果RawData为null -这将打破流并返回默认值。
float f()
{
if (RawData == null)
{
throw new NullReferenceException();
return default(float);
}
return doOtherOperation(RawData);
}
float doOtherOperation(PointF[] RawData)
{
//do what you wanted to do
return default(float);
}