接口实现中使用更具体属性类型为何非法?有无合法实现方式?
MyInterface with IList<string> Great question! The problem with your original code is that C# requires exact return type matching for implicit interface implementations. Your MyClass defines a Things property with IList<string>, which the compiler treats as a brand-new class property—not the implementation of MyInterface.Things (which expects ICollection<string>). That's why you get a compiler error.
Luckily, there are two solid ways to fix this:
1. Explicit Interface Implementation + Class-Specific Property
Use explicit interface implementation to satisfy the interface contract, then expose a public IList<string> property for direct use with MyClass instances:
interface MyInterface { ICollection<string> Things { get; } } class MyClass : MyInterface { // Explicitly implement the interface member (only accessible via MyInterface type) ICollection<string> MyInterface.Things => this.Things; // Public property with the more specific IList<string> type public IList<string> Things { get; } = new List<string>(); }
How this works:
- The explicit implementation (
MyInterface.Things) maps directly to the interface's required return type. When you cast aMyClassinstance toMyInterface, this is the property that gets used. - The public
Thingsproperty lets consumers work with the more capableIList<string>type when usingMyClassdirectly.
2. Use C# 9.0+ Covariant Return Types
If you're using C# 9 or later, you can take advantage of covariant return types, which allow implementing interface members with a more derived return type:
interface MyInterface { ICollection<string> Things { get; } } class MyClass : MyInterface { // Directly implement the interface with IList<string> (C# 9+) public IList<string> Things { get; } = new List<string>(); }
How this works:
- Covariant return types let you return a subtype (like
IList<string>, which inherits fromICollection<string>) when implementing an interface member that expects a base type. The compiler recognizes this as a valid implementation of the interface contract. - This is the cleaner option if your project supports C# 9 or newer.
内容的提问来源于stack exchange,提问作者Hiram Katz

