我正在尝试为项目创建类型化对象列表,但意识到我在创建新的父类型化对象列表并用子类型化对象列表填充它时遇到了麻烦。
用例是我稍后将实例化子类型对象,每个对象将执行自己的任务
这是失败的基本示例
public class test
{
public interface IParent { }
public partial class parent
{
public void Run() { }
}
public class child : parent, IParent
{
public new void Run() { }
}
public class box<T> where T : parent, new()
{
//public static implicit operator box<T>(box<child> v) => v;
public box()
{
new T().Run();
}
}
test()
{
box<parent> box = new box<child>();
}
}
我收到错误
Error CS0029 Cannot implicitly convert type 'xxx.test.box<xxx.test.child>' to 'xxx.test.box<xxx.test.parent>'
我找到了一些隐式转换的代码示例(已注释),但我也不知道如何在那里将框转换为框。
希望得到一些指导。
您可以引入带有通用协变 (
out
) 参数的简单接口,而不是隐式运算符:
public interface IBox<out T>
{
public T BoxedInstance { get; }
public void Unpack();
}
并让
Box
实现该接口并提供所需的通用约束。包括命名样式“fix”(如@Progman注意到的)和@Poul Bak对new
关键字替换的建议,结果代码可能如下所示:
public class Box<T> : IBox<T> where T : IParent, new()
{
public T BoxedInstance { get; }
public Box() => BoxedInstance = new T();
public void Unpack() => Instance.Run();
}
public interface IParent
{
public void Run();
}
public class Parent : IParent
{
// As Poul Bak suggested in comments, use "virtual" keyword
// to be able to override it in child classes
public virtual void Run() => Console.WriteLine("Parent Run");
}
public class Child : Parent
{
// As Poul Bak suggested in comments, using "override" keyword
// allows you to reimplement method behaviour in child class
public override void Run() => Console.WriteLine("Child Run");
}
现在您可以通过界面将“装箱子”对象分配为“装箱父”对象:
IBox<Parent> parentBox = new Box<Child>();
parentBox.Unpack();
有关协方差和相关内容的更多信息,您可以在 documentation 中找到,或者直接在 StackOverflow 中搜索 - 这里还有很多相关的帖子和答案(如 this)。