Start here. This is the direct spoken answer to practice first.
Why this question matters
Polymorphism is safe only when implementations preserve the contract callers rely on. Matching method signatures is not enough if one implementation rejects normal inputs or changes the meaning of success.
Each implementation must honor the interface's documented behavior: accepted inputs, returned results, failure cases, and important side effects. A subtype should not require stronger preconditions or provide weaker guarantees than the abstraction promises. If read-only storage cannot support WriteAsync, throwing NotSupportedException may show that the interface combines capabilities that should be modeled separately.