One of the big advantages of discriminated unions is that the set of possible cases is known at compile-time, so the compiler can tell you when your code doesn't handle a possible case. This helps a lot with refactoring as you can add a new case to an existing union and the compiler will tell you what places in the code need to be changed.
Another benefit is that pattern-matching on discriminated unions is syntactically elegant - you can write very clear code.
In theory you can probably dynamically generate a DU with Reflection.emit, or perhaps even add new cases to an existing one. However neither of the advantages above will apply so I don't really see much point in using them at all.
A standard inheritance model is also the right way to deal with dynamically loaded plugins, IMO. Define an interface or common base class in a DLL that each plugin depends on, have the plugin define a class that implements it, and then use methods on that interface/base class on the plugin once loaded.
DUs are designed to fix the set of possible /values/ in advance but make it easy for anyone to write a new function over the DU, whereas object-oriented inheritance is designed to fix the set of possible basic /functions/ in advance but make it easy for anyone to add new values. Since loading code dynamically is all about adding new values, I think it's a very natural fit.
It's worth mentioning in passing that DUs are actually implemented using .NET inheritance by the F# compiler - there's a base class for the entire union type, and then individual derived classes for each union case (though I think argument-less cases get treated specially).