[英]C#: Question about using generics and picking a random type
在我的游戲中,我使用的是開機系統,基本上是這樣的:
給玩家隨機加電的代碼如下:
Type t = RandomManager.PickFromParams<Type>(typeof(PowerupInvincible), typeof(PowerupDoubleFireRate));
ply.AddPowerup<t>();
並且AddPowerup<>()
方法如下所示:
public void AddPowerup<T>() where T : PowerupEffect, new()
{
var powerup = new T();
powerup.Activate(this);
powerups.Add(powerup);
}
現在,問題出在ply.AddPowerup<t>()
行,因為它抱怨找不到類型t:
找不到類型或名稱空間名稱“ t”(您是否缺少using指令或程序集引用?)
有人知道是否有解決此問題的方法,或者如果不可能解決,請向我展示一種更好的解決方法? 提前致謝!
聽起來您在這種情況下沒有正確使用泛型。 我假設PowerupInvincible
和PowerupDoubleFireRate
從某些PowerupBase
繼承:
PowerupBase powerUp = RandomManager.PickFromParams<PowerupBase>(typeof(PowerupInvincible), typeof(PowerupDoubleFireRate));
ply.AddPowerup(powerUp);
那么簡單的方法簽名就必須是:
public void AddPowerup(PowerupBase powerup)
{
powerup.Activate(this);
powerups.Add(powerup);
}
您的隨機管理器將負責選擇參數之一,實例化它,然后返回實例。
泛型是編譯類型。 t
是運行時的類型。 您將必須使用反射或調用該方法。
你可以做類似的事情
public void AddPowerup(Type powerupType) {
if (!powerupType.IsSubclassOf(typeof(PowerupEffect)))
throw some exception here;
var powerup = Activator.Create(powerupType);
....
}
您可以修復它-但只能通過反射-您必須找到AddPowerup的MethodInfo,使用類型t從中生成通用版本,然后為對象層調用此方法。
您不能在運行時傳遞Type參數,而只能在編譯時傳遞。 因此,您將需要對類型進行硬編碼,而不是使用t。
您可能應該考慮使用依賴項注入,其中AddPowerup()實際上並不創建新的PowerupEffect,而是通過參數獲取PowerupEffect對象。
該T
在<T>
應的類型的真實姓名,不類型的變量Type
。
實例化泛型類型在這里描述 :
// Use the typeof operator to create the generic type // definition directly. To specify the generic type definition, // omit the type arguments but retain the comma that separates // them. Type d1 = typeof(Dictionary<,>); // You can also obtain the generic type definition from a // constructed class. In this case, the constructed class // is a dictionary of Example objects, with String keys. Dictionary<string, Example> d2 = new Dictionary<string, Example>(); // Get a Type object that represents the constructed type, // and from that get the generic type definition. The // variables d1 and d4 contain the same type. Type d3 = d2.GetType(); Type d4 = d3.GetGenericTypeDefinition();
關於反射的好處是,您可以不必編寫一系列實現器的代碼:
// TODO proper caching
// TODO proper random generation
var randomType = Assembly.GetAssembly(typeof(MainClass))
.GetTypes()
.Where(t => typeof(B).IsAssignableFrom(t))
.Where(t => !(t.IsAbstract || t.IsInterface))
.Except(new [] { typeof(PowerupBase) })
.OrderBy (t => new Random(DateTime.Now.Millisecond).Next())
.First();
Activator.CreateInstance(x);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.