如何解决TargetManager实例化时的CS0266类型转换错误?
问题场景
我定义了如下两个接口:
public interface ITargetManager: ITargetManager<TargetManager, Target> { } public interface ITargetManager<TSelf, T> where TSelf : TargetManager<TSelf,T> where T : Target { int Prop1 { get; } string Prop2 { get; } int? Prop3 { get; } string Prop4 { get; } T Build(); void Update(T target); TSelf WithProp1(int value); TSelf WithProp2(string value); TSelf WithProp3(int? value); TSelf WithProp4(string value); }
接着实现了继承该接口的抽象类:
public abstract class TargetManager<TSelf, T> : ITargetManager<TSelf, T> where TSelf : TargetManager<TSelf, T> where T : Target { private int prop1; private string prop2; private int? prop3; private string prop4; private static ConcurrentDictionary<Type, MethodInfo> dic = new(); public TargetManager(T? target = null) { if (target == null) return; WithProp1(target.Prop1); WithProp2(target.Prop2); WithProp3(target.Prop3); WithProp4(target.Prop4); } public int Prop1 => prop1; public string Prop2 => prop2; public int? Prop3 => prop3; public string Prop4 => prop4; public TSelf WithProp1(int value) { prop1 = value; return this; } public TSelf WithProp2(string value) { prop2 = value; return this; } public TSelf WithProp3(int? value) { prop3 = value; return this; } public TSelf WithProp4(string value) { prop4 = value; return this; } public T Build() => (T)Activator.CreateInstance(typeof(T), this)!; public void Update(T target) { var methodInfo = dic.GetOrAdd(typeof(T), getUpdateMethodInfo); methodInfo.Invoke(target, new object[] { this }); } private static MethodInfo getUpdateMethodInfo(Type optionType) { var types = getInheritanceHierarchy(typeof(T)); var methods = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(mi => mi.Name == "Update"); return types.Join( methods, t => t.Name, mi => mi.DeclaringType.Name, (t, mi) => mi) .First(); } private static IEnumerable<Type> getInheritanceHierarchy(Type type) { for (var current = type; current != null; current = current.BaseType) { yield return current; } } public static implicit operator TSelf(TargetManager<TSelf, T> builder) { return (TSelf)builder; } }
最后实现了继承该抽象类的具体类:
public class TargetManager : TargetManager<TargetManager, Target> { public TargetManager(Target? target = null) : base(target) { } }
尝试通过sutManager = new TargetManager();实例化该具体类时,出现如下错误:
Severity Code Description Project File Line Suppression State
Error CS0266 Cannot implicitly convert type 'BuilderTest.TargetManager' to 'BuilderTest.ITargetManager'. An explicit conversion exists (are you missing a cast?) BuilderTest C:\Users\S.monzavi\source\repos\BuilderTest\BuilderTest\UnitTest1.cs 16 Active
解决方案
原因分析
具体类TargetManager仅继承了泛型抽象类TargetManager<TargetManager, Target>,该抽象类实现的是泛型接口ITargetManager<TargetManager, Target>。非泛型接口ITargetManager虽然继承了泛型版本,但具体类并没有显式实现这个非泛型接口,因此编译器无法自动将具体类实例隐式转换为ITargetManager类型。
解决方法
方法一:让具体类显式实现非泛型接口
修改具体类的定义,添加ITargetManager接口实现:
public class TargetManager : TargetManager<TargetManager, Target>, ITargetManager { public TargetManager(Target? target = null) : base(target) { } }
这样编译器就能识别具体类与非泛型接口的继承关系,允许隐式转换。
方法二:调整变量声明类型
如果不需要使用非泛型接口ITargetManager,可以直接将变量声明为具体类类型或泛型接口类型:
// 声明为具体类类型 TargetManager sutManager = new TargetManager(); // 或者声明为泛型接口类型 ITargetManager<TargetManager, Target> sutManager = new TargetManager();
内容的提问来源于stack exchange,提问作者shirin monzavi

