如何处理ArgumentOutOfRangeException

时间:2017-03-06 20:07:35

标签: c# .net exception-handling

我有一个通用的ListManager类,其方法是返回特定索引处的对象。我正在检查索引是否在范围内以避免异常。如果索引超出范围,我该怎么办?我试图返回null,但这是不可能的。我想这样做而不使用try catch。有什么建议吗?

public T GetAt<T>(int index)
{
    if (index <= list.Count() - 1)
        return list[index];
    else
        return null; //This will not compile
}

3 个答案:

答案 0 :(得分:4)

您可以返回default(T) null作为参考类型。但是对于值类型,您将返回一些默认值,例如0表示int。也许是,你想要的。

答案 1 :(得分:1)

为了在索引超出范围时返回null,您可以为值和引用类型编写2个版本

public class ValMgr<T> where T : struct
{
    public List<T> list;
    public T? GetAt(int index, T? defv = null)
    {
        if (index < list.Count)
        {
            return list[index] as T?;
        }
        return defv;
    }
}

并且

 public class RefMgr<T> where T : class
 {
     public List<T> list;
     public T GetAt(int index, T defv = null) 
     {
         // don't reinvent the wheel
         T ret =  list.ElementAtOrDefault(index) as T;
         return (ret == null) ? defv : ret;
     }    
 }

演示用法

var m = new ValMgr<int>();
m.list = new List<int>() { 1 };
var test1 = m.GetAt(0); // 1
var test2 = m.GetAt(1); // null
var test2bis = m.GetAt(1,-1); // -1
var n = new RefMgr<string>();
n.list = new List<string>() { "1" };
var test3 = n.GetAt(0); // "1"
var test4 = n.GetAt(1); // null
var test4bis = n.GetAt(1,"--"); // --

但请注意,如果您只想返回引用类型nulldefault,则可以始终使用标准Linq ElementAtOrDefault 值类型的值。

答案 2 :(得分:0)

通常,使用这样的通用方法,您希望调用者知道他们将无效值传递给您的方法。由于类型是不可为空的,因此正确的做法是将异常抛回给调用者。你可以不管它,让ArgumentOutOfRangeException气泡回到调用者。或者,如果您想使用自己的自定义异常类型或消息,您将捕获ArgumentOutOfRangeException,并实例化您自己的异常,将内部异常设置为您捕获的ArgumentOutOfRangeException。

如果你不想使用try / catch,你可以使用你现有的逻辑,但是在“else”部分,抛出你自己的异常,没有内部异常。

唯一的另一种选择是返回默认值(t),但我不建议这样做。如果你这样做,那么该方法的调用者将不会知道他们试图访问无效值,并且可能会以他们的快乐方式相信他们获得的默认值(例如,0表示int或false表示bool的情况)是存储在请求索引中的实际值,这很可能导致其解决方案中的错误。