开发者

Are nested try catches plausible in this instance?

If you have a brute force search where the user doesnt know the data type then can 开发者_运维技巧we do something like this?

        if (search.Length > 0 && comboBox1.Text.Equals("Data Type Not Known"))
        {
            try
            {
                ParentGraph p = new ParentGraph(search);
            }
            catch (NoDataFoundException ndfe)
            {
                //it fails so try different data type
                try
                {
                    CompoundGraph c = new CompoundGraph(search);
                }                
                catch(NoDataFoundException ndfe)
                {
                    //failed so try final type
                    try
                    {
                        BatchGraph b = new BatchGraph(search);
                    }
                    catch(NoDataFoundException ndfe)
                    {
                        MessageBox.Show("Data could not be linked to a particular search")
                    }
                }
            }
        }


That will work, but it's ugly in two ways:

  • It feels like the code duplication is a bad idea... could you have a List<T> of some kind, e.g. List<Func<string, object>> and try each factory delegate in turn?
  • If it's reasonable for the data not to be found, it shouldn't be an exception. Consider writing a factory method instead of a constructor, and return null if no data is found... or have a TryGetData with an out parameter and a bool return value (or maybe just a tuple return value). Handling this flow with exceptions doesn't feel right to me.


Apart from throwing exceptions more often than you should, it looks like your search constructor might be doing more work than it should. I would expect all instances to be instantiated using a light constructor, and then make them do the actual work when a method is invoked, e.g.:

// initialize graph
IGraph p = new ParentGraph();

// get the results (although count may be zero)
IEnumerable<Result> results = p.GetResults(search); // never throws an exception

A common interface would look something like:

interface IGraph
{
    IEnumerable<Result> GetResults(string search); 
}

If all your Graph instances implemented IGraph, you could use them like this:

IEnumerable<IGraph> knownGraphs = new IGraph[] 
{
    new ParentGraph(),
    new CompoundGraph(),
    ...
}

// get results from the first graph which can give them
foreach (IGraph graph in knownGraphs)
{
   List<Result> results = graph.GetResults(search).ToList()
   if (results.Count > 0)
      return results;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜