2011-08-22 63 views
2

在我的遊戲我使用的是上電系統,其基本工作原理是這樣的隨機類型的問題:C#:關於使用泛型和採摘

  • 敵人被打死,有隨機機率掉落通電箱
  • 皮卡上電箱獲得隨機項

爲給玩家隨機通電看起來像這樣的代碼...

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指令或程序集引用?)

有誰知道是否有解決這個問題的一種方式,或者如果這是不可能的,給我一個更好的辦法ŧ o做到了嗎?提前致謝!

回答

3

聽起來你在這個例子中沒有正確使用泛型。我假設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); 
} 

你隨機經理將負責選擇的參數之一,實例它,然後返回實例。

+0

這使我的代碼有很多更好,更潔淨!乾杯! – Dlaor

0

你能解決這個問題 - 但只有與反思 - 你必須找到一個MethodInfo爲AddPowerup,做一個通用版本從它與T類型,然後調用該對象層這種方法。

1

,你可以這樣做

public void AddPowerup(Type powerupType) { 
    if (!powerupType.IsSubclassOf(typeof(PowerupEffect))) 
     throw some exception here; 
    var powerup = Activator.Create(powerupType); 
    .... 
} 
0

你不能在運行時通過類型參數,只編譯時間。所以你需要對類型進行硬編碼而不是使用t。

您應該考慮使用依賴注入,其中AddPowerup()實際上並不創建新的PowerupEffect,而是通過參數獲取PowerupEffect對象。

0

T<T>應該是一個類型的真實名稱,而不是Type類型的變量。

0

實例化泛型類型is described here

// 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); 
+0

增加了基於動態隨機工廠樣本的反射 – sehe