【问题标题】:Increase readability in this try-catch?增加这个 try-catch 的可读性?
【发布时间】:2013-05-29 14:56:48
【问题描述】:

我想知道是否有更美观/更易于阅读的方式来编写以下内容:

for (int i = 0; i < 100; i++)
{ 
    // If m.GetString(i) throws an exception, continue.
    // Otherwise, do stuff.       
    try
    {
        string s = m.GetString(i);
        continue;
    }           
    catch (InvalidCastException) 
    { 
    }

    // do stuff with the message that you know is not a string.
}

这是 m 的样子:

msg[0] = 10
msg[1] = "string"
msg[2] = 2.224574743
// Etc.
// Assume it's different every time.

因此,当我在本例中执行m.GetString(0) 时,它会引发异常,因为msg[0]uint 而不是string。这是我用来获取类型的,因为m 不包含 GetType,我无法编辑 m。

m 是我无法编辑的库中 Message 类的实例。

然而,尽管这工作得很好,但为了获取类型而故意创建异常(即使它在 try-catch 中)感觉效率低下(当然也不利于读者)。

有更好的方法还是我坚持这个?

编辑:好的,我对Message 类进行了更多研究(我应该一开始就这样做,我很抱歉)。这是一个IEnumerable&lt;object&gt;

【问题讨论】:

  • 如果你可以避免异常,你应该......异常会增加开销
  • 您应该找出 m.GetString() 抛出的异常类型(假设您无法访问其背后的代码并在没有异常的情况下处理它)然后只捕获该类型的异常。抓住每一个可能的异常并继续下去并不好
  • m的类型是什么?
  • 您能否修改 GetString 以避免抛出异常并返回 null 以防万一它不是字符串并且排除 null 字符串或指示值是否为字符串 + 输出参数的布尔值以返回该值字符串
  • 就像 Matthew 说的,m 是什么?您总是可以将项目放入对象变量中,然后执行 gettype。

标签: c# optimization code-readability


【解决方案1】:

现在我知道mIEnumerable&lt;object&gt;,我认为这可能是你最好的选择:

foreach (string s in m.OfType<string>())
{
    // Process s, which can't be null.
}

很好很简单,它似乎可以处理您想要的所有逻辑,即它只会处理序列中的字符串项,并且会忽略所有其他类型的对象。

但是正如 Servy 指出的那样,这不会处理列表中的空值,因为 null 根本没有任何类型。


[在知道m的类型之前我之前的回答]

我认为您可以采取以下三种方法之一:

(1) 将bool TryGetString(int index, out string) 方法添加到您示例中的m 类型,然后执行

if (m.TryGetString(i, out s)) 
    // Process s (need to check for null!) 

(2) 添加一个bool IsString(int index) 方法并在调用GetString() 之前调用它。

if (m.IsString(i)) 
{
    s = m.GetString(i); 
    // Process s (need to check for null!) 

(3) 或者,您可以通过 GetObject(int index) 之类的方式公开该项目,然后执行 Iiya 建议的操作:

 string s = m.GetObject(i) as string; 

 if (s != null) 
     // Process s 

我认为 (1) 或 (3) 是最好的,尽管如果我们有更多关于 m 的信息,我们可能会提出更好的解决方案。

【讨论】:

  • 是的,m 是一个 IEnumerable。我现在将尝试您的第四个选项。
  • 请注意,如果您有任何null 对象应该 表示可能有问题的字符串;在不知道您的数据以及您期望如何使用它的情况下,我们无法知道它是否合适。
  • 是的,Servy 有一个很好的观点。如果对象列表中的一项为空,则它不能具有任何类型(因为当然没有对象具有任何类型!)
  • @TakoM。抱歉,我已经编辑掉了我的旧答案;但既然你引用了它,我现在就恢复它了。
【解决方案2】:

如果您只想处理非强类型数据序列中的字符串,请使用下一个代码:

for (int i = 0; i < 100; i++)
{ 
    string s = m[i] as string;

    if(s != null)
    {

    }
}

【讨论】:

  • 这是否仍然允许非字符串,因为有些类型可以成功转换为字符串?
  • @emd string 是密封的,所以它不能有子类型,因此除了string 之外没有任何类型可以转换为字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
相关资源
最近更新 更多