I think this sums it up:
Types that use a dual interface allow
clients to bind to a specific
interface layout. Any changes in a
future version to the layout of the
type or any base types will break COM
clients that bind to the interface. By
default, if the
ClassInterfaceAttribute attribute is
not specified, a dispatch-only
interface is used.
http://msdn.microsoft.com/en-us/library/ms182205.aspx
It increases the possibility that changing something in that class with the auto dual attribute will break someone else's code when the class is changed. If gives the consumer the ability to do something that will quite possibly cause them issues in the future.
The next option is ClassInterfaceType.AutoDual. This is the quick and dirty way to get early binding support as well (and make the methods show up in VB6 IntelliSense). But it's also easy to break compatibility, by changing the order of methods or adding new overloads. Avoid using AutoDual.
http://www.dotnetinterop.com/faq/?q=ClassInterface
I finally found the link that talks about what is going on with AutoDual and how it works:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7fa723e4-f884-41dd-9405-1f68afc72597
The warning against AutoDual isn't the
fact that dual interfaces is bad but
the fact that it auto-generates the
COM interface for you. That is bad.
Each time the COM interface has to be
regenerated you'll get a new GUID and
potentially new members. If the GUID
changes then you get a brand new
interface/class as far as COM is
concerned. For early binding you'd
have to rebuild the clients each time
the interface was regenerated. The
preferred approach is to define the
COM class interface explicitly with a
GUID. Then all the early binding
clients can use the defined interface
and not worry about it changing on
them during development. That is why
the recommended option is None to tell
the CLR not to auto-generate it for
you. You can still implement the dual
interface though if you need it.