C#泛型接口集合实现及IExportConfiguration类型转换错误如何解决
问题原因
C# 泛型接口默认是不变的,且bool属于值类型,即使为泛型接口添加协变修饰符,值类型也不支持协变转换,因此无法直接将IExportConfiguration<bool>实例强制转换为IExportConfiguration<object>。
解决方案
最通用的实现方式是抽离非泛型基接口,存放所有和泛型参数无关的属性,兼容不同类型的泛型配置实例:
1. 新增非泛型基接口
public interface IExportConfiguration { string Description { get; } Guid Id { get; } string Name { get; } object Value { get; set; } }
2. 修改原有泛型接口继承非泛型基接口
public interface IExportConfiguration<T> : IExportConfiguration { // 用new关键字隐藏基接口的Value属性,对外暴露强类型定义 new T Value { get; set; } }
3. 调整抽象类实现非泛型接口属性
在ExportConfiguration<T>中显式实现非泛型接口的Value属性,完成类型转换:
public abstract class ExportConfiguration<T> : IExportConfiguration<T> { public abstract string Description { get; } public abstract string Name { get; } public abstract Guid Id { get; } public abstract T Value { get; set; } public abstract T DefaultValue { get; set; } // 显式实现非泛型接口的Value属性 object IExportConfiguration.Value { get => Value; set => Value = (T)value; } public virtual void SetValue(ICollection<KeyValuePair<Guid, object>> values) { if (values.Any(kvp => kvp.Key == this.Id)) Value = (T)values.First(kvp => kvp.Key == this.Id).Value; else Value = this.DefaultValue == null ? this.DefaultValue : default(T); } }
4. 修改配置集合的类型定义
将IConfigurableExport中的配置集合改为非泛型基接口类型:
public interface IConfigurableExport { ICollection<IExportConfiguration> Configurations {get;} }
5. 调整导出器的实现
无需再做强制类型转换:
public class MyExporter : IConfigurableExport { MyConfig conf = new MyConfig(); public ICollection<IExportConfiguration> Configurations { get { return new List<IExportConfiguration> { conf }; } } }
效果验证
原有Main方法无需任何修改,运行后会正常输出My Config Name。UI层面可以直接通过非泛型接口读取所有通用属性渲染配置界面,需要获取强类型值时再对配置项做类型转换即可。
内容的提问来源于stack exchange,提问作者Adam H
相关产品推荐
相关产品推荐

