要返回的值表示无效值

时间:2009-05-07 09:28:28

标签: c#

假设您有一个返回枚举的函数:

public enum ServerStatus
{
    Down,
    Up
}

private ServerStatus GetServerStatus(int time)
{
    if (time >= 0 && time < 12)
    {
        return ServerStatus.Down;
    }
    else if (time >= 12 && time <= 23)
    {
        return ServerStatus.Up;
    }
    else
    {
        return ?? // Server status is neither Up nor Down
    } 
}

我应该:

  1. 将“Neither”添加到ServerStatus
  2. 使GetServerStatus返回ServerStatus?并返回null
  3. 返回另一个bool,指示值是否有意义

5 个答案:

答案 0 :(得分:13)

如果这种情况在实践中永远不会发生,并且您不希望产生除“向上”和“向下”之外的其他内容,那么您应该抛出异常。

答案 1 :(得分:2)

如果您不想抛出异常,那么您可能总是有一个未知的枚举值。例如,服务器状态可以是Up,Down或Unknown。在某些情况下,未知状态可能有效(例如,如果您无法连接到服务器)。可以像布尔值一样测试这个未知值,以确定答案是否有意义。

我并不是说这比ArgumentOutOfRangeException更好,只是它是另一种处理问题的方法。您的调用代码总是可以根据其他条件抛出异常。

答案 2 :(得分:2)

private ServerStatus GetSeverStatus(int time)
{
    if (time >= 0 && time < 12)
    {
        return ServerStatus.Down;
    }

    if (time >= 12 && time <= 23)
    {
        return ServerStatus.Up;
    }

    throw new ArgumentOutOfRangeException();
}

答案 3 :(得分:1)

这是“如何强制执行我的功能前置条件”的情况。你有几种方法可以做到。

我真正理解的一种方法是:有一个非常简单的“按合同编程”函数来处理纯业务逻辑:断言有效的前提条件。在此基础上构建“安全”功能,确保输入 有效。

// with a 'validity' return type
public Pair<bool,ServerStatus> checkedGetServerStatus( uint time ) {
   Pair<bool,ServerStatus> p;
   p.first = false;
   if( time > 23 ) return p;

   p.first = true;
   p.second = GetServerStatus( (int)time );
   return p;
}

// or with an exception
public ServerStatus GetServerStatusEx( uint time ) {
   if( time > 23 ) throw InvalidArgumentException(time);

   return GetServerStatus( (int)time );
}

另一种可能更好的方法是将提供的函数参数类型更改为不会出错的内容。

class ServerTime {
    public ServerTime( uint hours ) { seconds = (hours%24)*3600; }
    private uint seconds;
}

public ServerStatus GetServerStatus( ServerTime time ) {
...
}

答案 4 :(得分:0)

我的想法是这样的:

如果这是一个例外情况(10,000个电话中有1个,一年一次?)或不可恢复的错误,则提出异常。

如果“未知”案例不是例外或者是可恢复的错误,我会使用“未知”值。那么问题就是你添加第三个值还是使用可空类型?

如果很可能那么添加第三个状态“未知”或“无法获得”。

如果不太可能那么可以使用可空类型。

您使用哪种解决方案可能需要某种方法来找出无法确定服务器状态的确切原因 - 可能没有连接,用户凭据可能无效,可能存在太多连接等等。确定是否立即重试,在延迟一段时间后重试或直接中止。