簡體   English   中英

C#:有關使用泛型和選擇隨機類型的問題

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

有人知道是否有解決此問題的方法,或者如果不可能解決,請向我展示一種更好的解決方法? 提前致謝!

聽起來您在這種情況下沒有正確使用泛型。 我假設PowerupInvinciblePowerupDoubleFireRate從某些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是運行時的類型。 您將必須使用反射或調用該方法。

http://blogs.microsoft.co.il/blogs/gilf/archive/2008/10/10/invoking-generic-methods-with-reflection.aspx

你可以做類似的事情

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM