Background information: starting with version 0.96, dbscript was capable of dealing with more than 1 database engine (i.e. other than MSSQL), and the question I had to solve was how the user interface would reflect the different capabilities of the database modules.
DBEngine +-- MSSql.DBEngine +-- Oracle.DBEngine +.. other derived classes
For example, a database module might implement the “Import”, “Upload”, or “Generate Script” function, but how does the module let its capabilities be known to the rest of the code.
There are several possibilities:
- Boolean flags (e.g. CanImport) and an implementing method (DoImport())
- [Flags] enumeration and corresponding implementing methods
Both bools and enumerations are easy to implement, but they don’t scale if you have a lot of features to take care of, and there is no strong link between the information and the implementation.
Using interfaces, the capabilities problem is solved by declaring and implementing interfaces (such as IDBEngineImport) and checking whether the module implements an interface. The only question remaining is: How does it perform?
Well, other people have asked that question before, and others have answered it:
C# ‘is’ operator performance (stackoverflow)
What are the performance characteristics of ‘is’ reflection in C#? (stackoverflow)
Prefix-casting versus as-casting in C#
Type casting impact over execution performance in C#
and the answer seems to be: It does not really matter.
However the answers behind above links are the same:
- If you just want to check for an interface implementation, use “is”.
- If you need the type-cast object, use “as” and check for null.
- Don’t use () type cast operators if you don’t know if the cast will always be successful, as exceptions have a performance penalty.
Pingback: Creating MediaWiki Documentation of PostgreSQL Databases « devioblog