[英]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.