Q:

Polymorphism design question

First of all sorry for the long question, but I couldn't write it any shorter :)
Real world example: we have large roll of paper, which contains small 'stickers' printed on them. Each sticker has a code. First two letters of the code tells us what kind of a sticker this is (sticker that represents new roll, sticker that represents end of current roll, sticker which should go to quality control,... but most of them are normal enumerated stickers).
For example sticker with the code XX0001 means, that after it there should be only normal enumerated codes (like NN0001 to NN9999), always the same number. Code QC0001 tells us, that next 10 codes (from QC0001 to QC0010) should go to quality control.
I designed the application so, that each type of a sticker is its own class - NormalSticker, BadSticker, ControllSticker, QualitySticker,... They all inherit from a SticerBase class, which contains some common data for all of them (quality of the scan, date and time of the scan, content of the code). Instances of these classes are created in a static Parser class, which checkes the code and returns appropriate object back to us.
This all works OK, but now I got to a halt. I have also a Roll class, which has a set of Stickers, implemented as List<StickerBase>. This class has a public AddSticker(StickerBase) method, with which we add stickers to the roll. But this method should contain some logic, for example if we get the code XX001, then next 9999 stickers should be from NN0001 to NN9999. Only option I see here, is to make desicions based on the type of the sticker, like:
public void AddSticker(StickerBase sticker)
{
    if (sticker.GetType().Equals(typeof(StickerNewRoll)))
    {
        // Next 9999 sticker should be in the form of NN0001 to NN9999
    }

    if (sticker.GetType().Equals(typeof(EnumeratedSticker)))
    {
        // Add 9999 stickers to the list, other business logic...
    }

    if (sticker.GetType().Equals(typeof(QualitySticker)))
    {
        // Stop the machine and notify the worker
    }
}

I would be really surprised if this is the right approach. Any ideas?
Edit - possible solution: because for each sticker I know how the next one should look like, I can add new method public Sticker NextStickerShouldLookLike() method to each Sticker class. In the validation logic (similar to Péter Török's answer) I can just check if current sticker is the same as previousSticker.NextStickerShouldLookLike(). The Validate method would have two input parameters - current and previous sticker.

A:

Do you want to add the set of stickers associated with a specific sticker in a single move, or do you want to validate that stickers added conform to the constraints set by the latest special sticker?
In the first case you could add a polymorphic GetAssociatedStickers() method to your sticker classes, which returns the set of stickers from NN0001 to NN9999 to a sticker with code XX001, etc. Then you can add that set of stickers right after the control sticker.
Update
For validation, you could have a new interface StickerValidator, and a method GetValidator in your sticker classes. Special stickers would return a proper validator object (which could be implemented as an anonymous class or an inner class), while regular stickers would return null. Then AddSticker can be modified to look something like
public void AddSticker(StickerBase sticker)
{
    if (sticker.GetValidator() != null)
    {
        this.validator = sticker.GetValidator();
        // add the sticker to the list
    }
    else
    {
        if (this.validator == null || this.validator.validate(sticker))
        {
            // add the sticker to the list
        }
        else
        {
            // set error state
        }
    }
}

A:

Having conditional expression based on type is an antipattern, and you are correct in that you should try to avoid it. One of the problem is, for instance, that you will have to update this method whenever you create a new StickerBase sub-class. Another problem is that the method signature signals that a caller can pass any implementation of StickerBase, but in fact only a few are supported.
If possible, place your logic in the Sticker implementations. Have an abstract method in the StickerBase class and override in the sub-classes. This way you only need to make a method call in the AddSticker method and won't have to know about what kind of sticker is added.
If this isn't possible, and you really need to have your code dealing with different types of stickers in your Roll class, you might consider looking into the Visitor pattern. Try to avoid this and go with the first approach if possible, though. 

A:

I can see debate rages in the other answers, but I'm not sure if it's possible to come to a good solution without examining your example in more depth.
Firstly, you have three classes, the Roll, the Parser creating the stickers and the stickers themselves (divided into the derived classes). Perhaps there's another class implementing some business logic that you haven't mentioned? It might be worth describing...
The first question is:
Given that some class is responsible for attaching the stickers to the roll (the Parser class?), can you leave the roll entirely ambivalent to which stickers it's receiving, and place your logic elsewhere? Is the logic of what to do when sticker is of type X really something for the roll to know about, given that it's not the roll that's going out and getting the stickers?
The second is: 
How polymorphic ARE your stickers? Do they have different methods? Do they have different properties? Or are they similar enough that you can just put a label on a StickerBase class?
The third is: Should it be up to the stickers to tell the roll what to do? I.E. should the roll be calling the method sticker.TellMeWhatToDoNextPlease() (implemented as a virtual method and ovveridden in the derived classes of sticker) - especially as the roll isn't responsible for what people are trying to stick on it. You could ask the same question of the class that's responsible for putting the stickers on the roll. You could train a monkey to do it and let the roll figure it out, or you could put your logic there, (if it's where the stickers are being made it should already know what it's making) and let the roll accept what it's stuck with.
Basically - what controls your process? The roll of paper getting stickers stuck on it, the stickers themselves, or whatever makes and sticks the stickers?

