unity3d 具有继承/多态性的C#多级泛型

fykwrbwg  于 2022-12-30  发布在  C#
关注(0)|答案(1)|浏览(157)

我已经被这个问题难住了一段时间,但现在想知道是否有可能通过另一种方法,或者我只是错过了一步。
下面是基类。

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 {}

我想创建一个保持器/container类来保存我的EndType 0类的数组,它将在Unity中用于为我的StartType 0类绘制一个通用自定义属性抽屉。
任何正确方向的建议或指针都将是惊人的,因为我在过去的几个月里已经多次尝试解决这个问题。
我想我可以尝试提供每个参数,但我无法将StartType 0转换为EndType 0。

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];
    }
}

我想我可以尝试为StartType 0参数提供EndType 0,但我猜由于没有考虑多态性,它存在问题。

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”来扰乱泛型类型。

ukdjmx9f

ukdjmx9f1#

经过一些发挥周围的variance in 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"来扰乱泛型类型。

相关问题