[英]C# Multi Level Generics with inheritance/polymorphism
我已经为此困惑了一段时间,但想知道是否可以通过另一种方法实现,或者我只是错过了一步。
这是基类。
public class StartType0<T1, T2>
where T1 : StartType1
where T2 : StartType2
{}
public class StartType1 {}
public class StartType2 {}
public class EndType0 : StartType0<EndType1, EndType2> {}
public class EndType1 : StartType1 {}
public class EndType2 : StartType2 {}
我想创建一个持有人/容器 class 来保存我的 EndType0 class 的数组,它将在 Unity 中用于为我的 StartType0 class 绘制一个通用自定义属性抽屉。
任何正确方向的建议或指示都会很棒,因为在过去的几个月里我已经多次尝试解决这个问题。
我想我可以尝试提供每个参数,但我无法将 StartType0 转换为我的 EndType0。
public class TypeContainer<T0, T1, T2>
where T0 : StartType0<T1, T2>
where T1 : StartType1
where T2 : StartType2
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<StartType0<EndType1, EndType2>, EndType1, EndType2> container = new TypeContainer<StartType0<EndType1, EndType2>, EndType1, EndType2>();
public Tester()
{
EndType0 instance = (EndType0)container.array[0];
}
}
我想我可以尝试为 StartType0 参数提供 EndType0,但我猜它有问题,因为没有考虑多态性。
public class TypeContainer<T0, T1, T2>
where T0 : StartType0<T1, T2>
where T1 : StartType1
where T2 : StartType2
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<EndType0, EndType1, EndType2> container = new TypeContainer<EndType0, EndType1, EndType2>();
public Tester()
{
EndType0 instance = container.array[0];
}
}
理想情况下,我会喜欢以这种方式处理它,并涉及一些美味的多态性。
public class TypeContainer<T>
where T : StartType0<StartType1, StartType2>
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<EndType0> container = new TypeContainer<EndType0>();
public Tester()
{
EndType0 instance = container.array[0];
}
}
-编辑1-
在关注@JohnathanBarclay 的评论后,我设法做出以下决定。
public class StartType0<out T1, out T2>
where T1 : StartType1, IStartType1
where T2 : StartType2, IStartType2
{}
public interface IStartType1 {}
public class StartType1 : IStartType1 {}
public interface IStartType2 {}
public class StartType2 : IStartType2 {}
public class EndType0 : StartType0<EndType1, EndType2> {}
public class EndType1 : StartType1 {}
public class EndType2 : StartType2 {}
然后允许我执行以下操作并完成编译。
public class TypeContainer<T0, T1, T2>
where T0 : IStartType0<T1, T2>
where T1 : IStartType1
where T2 : IStartType2
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<EndType0, EndType1, EndType2> container = new TypeContainer<EndType0, EndType1, EndType2>();
public Tester()
{
EndType0 instance = container.array[0];
}
}
不过,这在统一编辑器中存在问题。
-编辑2-
经过一番尝试后,我找到了目前最理想的设置
public interface IStartType0<out T1, out T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{}
public class StartType0<T1, T2>
IStartType0<T1, T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{}
public interface IStartType1<out T> where T StartType1 {}
public class StartType1 : IStartType1<StartType1> {}
public interface IStartType2<out T> where T StartType2 {}
public class StartType2 : IStartType2<StartType2> {}
public class EndType0 : StartType0<EndType1, EndType2> {}
public class EndType1 : StartType1 {}
public class EndType2 : StartType2 {}
public class TypeContainer<T0, T1, T2>
where T0 : IStartType0<T1, T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<EndType0, EndType1, EndType2> container = new TypeContainer<EndType0, EndType1, EndType2>();
public Tester()
{
EndType0 instance = container.array[0];
}
}
有了“或多或少”有保证的基本类型,我就可以在这些基础类型上运行我的 CustomPropertyDrawer 并生成自定义检查器,甚至可以利用“Activator”来处理通用类型。
在 generics 中尝试了一些变化之后,我发现目前为止我的理想设置
public interface IStartType0<out T1, out T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{}
public class StartType0<T1, T2>
IStartType0<T1, T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{}
public interface IStartType1<out T> where T StartType1 {}
public class StartType1 : IStartType1<StartType1> {}
public interface IStartType2<out T> where T StartType2 {}
public class StartType2 : IStartType2<StartType2> {}
public class EndType0 : StartType0<EndType1, EndType2> {}
public class EndType1 : StartType1 {}
public class EndType2 : StartType2 {}
public class TypeContainer<T0, T1, T2>
where T0 : IStartType0<T1, T2>
where T1 : IStartType1<StartType1>
where T2 : IStartType2<StartType2>
{
public T0[] array = new T0[1];
public TypeContainer()
{
array[0] = Activator.CreateInstance(typeof(T0));
}
}
public class Tester
{
public TypeContainer<EndType0, EndType1, EndType2> container = new TypeContainer<EndType0, EndType1, EndType2>();
public Tester()
{
EndType0 instance = container.array[0];
}
}
有了“或多或少”有保证的基本类型,我就可以在这些基础类型上运行我的 CustomPropertyDrawer 并生成自定义检查器,甚至可以利用“Activator”来处理通用类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.