HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Lots of Continues in an Inner Loop and Dictionary of Actions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
continuesactionslooplotsanddictionaryinner

Problem

I'm using ABCPDF (Version 8) to update an existing PDF document and I believe its API is hurting me in this situation and was curious whether anyone had any comments on how this looks as it appears ugly to me.

The situation: I am replacing pages in PDF documents that are all generated by an in-house process so I can rely on their format being consistent and the following code is tasked with updating annotation links on the Table of Contents page(s) to point to the replace pages instead of the old pages. Since there can be multiple replacement operations, I decided to put the collection of these link annotations into a dictionary instead of looping through all of them for each replacement operation.

As my comments in the code mention, I only was able to piece this together by debugging a lot and examining the properties of different ABCPDF objects.

Here's the relevant code:

//use less than or equal to here because a one page TOC will have a matching start and end page number
private Dictionary> _linkUpdates;
WebSuperGoo.ABCPDF8.Doc pdfDoc;
for (var pageNumber = startPageNumber; pageNumber 
            {
                destinationPage.ID = updatedPageId;
                Atom.SetItem(destination, 0, destinationPage);
            }
        );
    }
}


I included the declarations of _linkUpdates and doc for reference. So after I have this collection populated, when I have an update to make, I can simply do this:

if (_linkUpdates.ContainsKey(oldPageId))
{
     _linkUpdates[oldPageId](newPageId);
}


I fully understand that this logic is heavily dependent on an understanding of how ABCPDF works, but since there's a fairly active community on SO, I figured this might get some responses, perhaps from somebody who knows of an easier way of getting at/updating these link annotations.

So, to summarize the areas I am interested in feedback on are:

  • The prevalence of continues in my inner for loop



  • The choice of using a dictionary with an Action valu

Solution

If you do this often, you could write an extension method for object that takes a function, which is executed only when the input is not null. You could then use it in a fluent manner to navigate multiple times:

public static class Navigator
{
    public static TOutput Navigate(
        this TInput input, Func navigationFunction)
        where TOutput : class
    {
        if (input == null)
            return null;

        return navigationFunction(input);
    }
}


Usage:

var destinationPage = 
    (annotationMaster.Resolve(Atom.GetItem(annotationMaster.Atom, 0)) as DictAtom)
        .Navigate(annotItem => annotItem["D"] as ArrayAtom)
        .Navigate(destination => destination[0] as RefAtom);

if (destinationPage == null)
    continue;


Notice that I also removed the braces. This is a matter of personal opinion (and sometimes company policy), but I think that they're not always necessary, especially when the body of the condition is this simple.

Code Snippets

public static class Navigator
{
    public static TOutput Navigate<TInput, TOutput>(
        this TInput input, Func<TInput, TOutput> navigationFunction)
        where TOutput : class
    {
        if (input == null)
            return null;

        return navigationFunction(input);
    }
}
var destinationPage = 
    (annotationMaster.Resolve(Atom.GetItem(annotationMaster.Atom, 0)) as DictAtom)
        .Navigate(annotItem => annotItem["D"] as ArrayAtom)
        .Navigate(destination => destination[0] as RefAtom);

if (destinationPage == null)
    continue;

Context

StackExchange Code Review Q#33579, answer score: 2

Revisions (0)

No revisions yet.